PKHeX/PKHeX/MainWindow/Main.cs

4253 lines
182 KiB
C#
Raw Normal View History

using PKHeX.Misc;
using System;
2014-06-28 21:22:05 +00:00
using System.Collections.Generic;
using System.Diagnostics;
2014-06-28 21:22:05 +00:00
using System.Drawing;
using System.Globalization;
2014-06-28 21:22:05 +00:00
using System.IO;
2015-02-13 04:26:23 +00:00
using System.Linq;
using System.Media;
2015-02-13 04:26:23 +00:00
using System.Text;
using System.Threading;
using System.Windows.Forms;
2014-06-28 21:22:05 +00:00
namespace PKHeX
{
public partial class Main : Form
2014-06-28 21:22:05 +00:00
{
public Main()
2014-06-28 21:22:05 +00:00
{
#region Initialize Form
new Thread(() => new SplashScreen().ShowDialog()).Start();
DragInfo.slotPkmSource = SAV.BlankPKM.EncryptedPartyData;
2014-06-28 21:22:05 +00:00
InitializeComponent();
// Check for Updates
L_UpdateAvailable.Click += (sender, e) => { Process.Start(ThreadPath); };
new Thread(() =>
{
string data = Util.getStringFromURL(VersionPath);
if (data == null)
return;
try
{
DateTime upd = DateTime.ParseExact(data, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
DateTime cur = DateTime.ParseExact(Properties.Resources.ProgramVersion, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
if (upd <= cur)
return;
string message = $"New Update Available! {upd.ToString("d")}";
if (InvokeRequired)
try { Invoke((MethodInvoker) delegate { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; }); }
catch { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; }
else { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; }
}
catch { }
}).Start();
CB_ExtraBytes.SelectedIndex = 0;
getFieldsfromPKM = populateFieldsPK6;
getPKMfromFields = preparePK6;
// Set up form properties and arrays.
SlotPictureBoxes = new[] {
bpkx1, bpkx2, bpkx3, bpkx4, bpkx5, bpkx6,
bpkx7, bpkx8, bpkx9, bpkx10,bpkx11,bpkx12,
bpkx13,bpkx14,bpkx15,bpkx16,bpkx17,bpkx18,
bpkx19,bpkx20,bpkx21,bpkx22,bpkx23,bpkx24,
bpkx25,bpkx26,bpkx27,bpkx28,bpkx29,bpkx30,
ppkx1, ppkx2, ppkx3, ppkx4, ppkx5, ppkx6,
bbpkx1,bbpkx2,bbpkx3,bbpkx4,bbpkx5,bbpkx6,
dcpkx1, dcpkx2, gtspkx, fusedpkx,subepkx1,subepkx2,subepkx3,
};
relearnPB = new[] { PB_WarnRelearn1, PB_WarnRelearn2, PB_WarnRelearn3, PB_WarnRelearn4 };
movePB = new[] { PB_WarnMove1, PB_WarnMove2, PB_WarnMove3, PB_WarnMove4 };
Label_Species.ResetForeColor();
2014-06-28 21:22:05 +00:00
// Set up Language Selection
2014-12-14 18:31:53 +00:00
foreach (var cbItem in main_langlist)
CB_MainLanguage.Items.Add(cbItem);
2014-06-28 21:22:05 +00:00
// ToolTips for Drag&Drop
new ToolTip().SetToolTip(dragout, "PKM QuickSave");
// Box Drag & Drop
foreach (PictureBox pb in SlotPictureBoxes)
{
pb.AllowDrop = true; // The PictureBoxes have their own drag&drop event handlers (pbBoxSlot)
pb.GiveFeedback += (sender, e) => { e.UseDefaultCursors = false; };
}
dragout.GiveFeedback += (sender, e) => { e.UseDefaultCursors = false; };
GiveFeedback += (sender, e) => { e.UseDefaultCursors = false; };
foreach (TabPage tab in tabMain.TabPages)
{
tab.AllowDrop = true;
tab.DragDrop += tabMain_DragDrop;
tab.DragEnter += tabMain_DragEnter;
}
foreach (TabPage tab in tabBoxMulti.TabPages)
{
tab.AllowDrop = true;
tab.DragDrop += tabMain_DragDrop;
tab.DragEnter += tabMain_DragEnter;
}
GB_OT.Click += clickGT;
GB_nOT.Click += clickGT;
GB_Daycare.Click += switchDaycare;
GB_RelearnMoves.Click += clickMoves;
TB_Nickname.Font = PKX.getPKXFont(11);
TB_OT.Font = (Font)TB_Nickname.Font.Clone();
TB_OTt2.Font = (Font)TB_Nickname.Font.Clone();
2016-03-23 03:30:48 +00:00
Menu_Modify.DropDown.Closing += (sender, e) =>
{
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
};
Menu_Options.DropDown.Closing += (sender, e) =>
{
if (!Menu_Unicode.Selected)
return;
if (e.CloseReason == ToolStripDropDownCloseReason.ItemClicked)
e.Cancel = true;
};
// Box to Tabs D&D
dragout.AllowDrop = true;
FLP_SAVtools.Scroll += Util.PanelScroll;
// Load WC6 folder to legality
refreshWC6DB();
#endregion
#region Localize & Populate Fields
string[] args = Environment.GetCommandLineArgs();
string filename = args.Length > 0 ? Path.GetFileNameWithoutExtension(args[0])?.ToLower() : "";
HaX = filename?.IndexOf("hax", StringComparison.Ordinal) >= 0;
bool showChangelog = false;
// Load User Settings
{
unicode = Menu_Unicode.Checked = Properties.Settings.Default.Unicode;
SaveFile.SetUpdateDex = Menu_ModifyDex.Checked = Properties.Settings.Default.SetUpdateDex;
SaveFile.SetUpdatePKM = Menu_ModifyPKM.Checked = Properties.Settings.Default.SetUpdatePKM;
// Select Language
string l = Properties.Settings.Default.Language;
if (l.Length != 2) l = "en";
int lang = Array.IndexOf(lang_val, l);
CB_MainLanguage.SelectedIndex = lang < 0 ? 1 : lang;
// Version Check
if (Properties.Settings.Default.Version.Length > 0) // already run on system
{
int lastrev; int.TryParse(Properties.Settings.Default.Version, out lastrev);
int currrev; int.TryParse(Properties.Resources.ProgramVersion, out currrev);
showChangelog = lastrev < currrev;
}
Properties.Settings.Default.Version = Properties.Resources.ProgramVersion;
Properties.Settings.Default.Save();
}
2014-08-17 01:42:51 +00:00
InitializeFields();
formInitialized = true;
2014-06-28 21:22:05 +00:00
#endregion
#region Load Initial File(s)
if (args.Length > 1) // Load the arguments
{
foreach (string arg in args.Skip(1).Where(a => a.Length > 4))
openQuick(arg, force: true);
}
2016-07-04 23:16:34 +00:00
if (!SAV.Exportable) // No SAV loaded from exe args
2016-04-09 05:14:16 +00:00
{
string path = null;
try
{
path = SaveUtil.detectSaveFile();
}
catch (Exception ex)
{
// Todo: translate this
ErrorWindow.ShowErrorDialog("An error occurred while attempting to auto-load your save file.", ex, true);
}
if (path != null && File.Exists(path))
openQuick(path, force: true);
2016-07-04 23:16:34 +00:00
else
loadSAV(SAV, null);
}
// Splash Screen closes on its own.
BringToFront();
WindowState = FormWindowState.Minimized;
Show();
WindowState = FormWindowState.Normal;
if (HaX) Util.Alert("Illegal mode activated.", "Please behave.");
if (showChangelog)
new About().ShowDialog();
2014-06-28 21:22:05 +00:00
#endregion
}
#region Important Variables
public static PKM pkm = new PK6(); // Tab Pokemon Data Storage
2016-07-04 23:16:34 +00:00
public static SaveFile SAV = new SAV6 { Game = (int)GameVersion.AS, OT = "PKHeX", TID = 12345, SID = 54321, Language = 2, Country = 49, SubRegion = 7, ConsoleRegion = 1 }; // Save File
2014-10-10 02:59:57 +00:00
public static string eggname = "";
public static string curlanguage = "en";
public static string[] gendersymbols = { "♂", "♀", "-" };
public static string[] specieslist, movelist, itemlist, abilitylist, types, natures, forms,
memories, genloc, trainingbags, trainingstage, characteristics,
encountertypelist, gamelanguages, balllist, gamelist, pokeblocks,
g3coloitems, g3xditems, g3items, g2items, g1items = { };
public static string[] metGSC_00000, metRSEFRLG_00000, metCXD_00000 = { };
public static string[] metHGSS_00000, metHGSS_02000, metHGSS_03000 = { };
public static string[] metBW2_00000, metBW2_30000, metBW2_40000, metBW2_60000 = { };
public static string[] metXY_00000, metXY_30000, metXY_40000, metXY_60000 = { };
public static string[] wallpapernames, puffs = { };
public static bool unicode;
2016-07-09 22:34:38 +00:00
public static List<ComboItem> MoveDataSource, ItemDataSource, SpeciesDataSource, BallDataSource, NatureDataSource, AbilityDataSource, VersionDataSource;
private static List<ComboItem> metGen2, metGen3, metGen3CXD, metGen4, metGen5, metGen6;
public static volatile bool formInitialized, fieldsInitialized, fieldsLoaded;
private static int colorizedbox = -1;
private static Image colorizedcolor;
private static int colorizedslot;
public static bool HaX;
private LegalityAnalysis Legality = new LegalityAnalysis(new PK3());
private static readonly Image mixedHighlight = Util.ChangeOpacity(Properties.Resources.slotSet, 0.5);
private static readonly string[] lang_val = { "ja", "en", "fr", "it", "de", "es", "ko", "zh", "pt" };
private static readonly string[] main_langlist =
{
"日本語", // JPN
"English", // ENG
"Français", // FRE
"Italiano", // ITA
"Deutsch", // GER
"Español", // SPA
"한국어", // KOR
"中文", // CHN
"Português", // Portuguese
};
private static GameVersion origintrack;
private readonly PictureBox[] SlotPictureBoxes, movePB, relearnPB;
private readonly ToolTip Tip1 = new ToolTip(), Tip2 = new ToolTip(), Tip3 = new ToolTip(), NatureTip = new ToolTip();
2014-06-28 21:22:05 +00:00
#endregion
2014-12-13 22:48:34 +00:00
#region Path Variables
public static string WorkingDirectory => Util.IsClickonceDeployed ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "PKHeX") : Environment.CurrentDirectory;
public static string DatabasePath => Path.Combine(WorkingDirectory, "db");
public static string WC6DatabasePath => Path.Combine(WorkingDirectory, "wc6");
private static string BackupPath => Path.Combine(WorkingDirectory, "bak");
private static string ThreadPath => @"https://projectpokemon.org/forums/showthread.php?36986";
private static string VersionPath => @"https://raw.githubusercontent.com/kwsch/PKHeX/master/PKHeX/Resources/text/version.txt";
#endregion
2014-12-13 22:48:34 +00:00
#region //// MAIN MENU FUNCTIONS ////
// Main Menu Strip UI Functions
private void mainMenuOpen(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
string pkx = pkm.Extension;
string ekx = 'e' + pkx.Substring(1, pkx.Length-1);
string supported = "*.pkm;";
for (int i = 3; i <= SAV.Generation; i++)
{
supported += $"*.pk{i}";
if (i != pkm.Format)
supported += ";";
}
OpenFileDialog ofd = new OpenFileDialog
{
Filter = $"Decrypted PKM File|{supported}" +
$"|Encrypted PKM File|*.{ekx}" +
"|Binary File|*.bin" +
"|All Files|*.*",
2016-02-01 07:15:54 +00:00
RestoreDirectory = true,
FilterIndex = 4,
FileName = "main",
};
2016-02-01 07:15:54 +00:00
// Reset file dialog path if it no longer exists
if (!Directory.Exists(ofd.InitialDirectory))
ofd.InitialDirectory = WorkingDirectory;
2016-02-01 07:15:54 +00:00
// Detect main
string path = SaveUtil.detectSaveFile();
if (path != null)
{ ofd.InitialDirectory = Path.GetDirectoryName(path); }
else if (File.Exists(Path.Combine(ofd.InitialDirectory, "main")))
{ }
else if (!Directory.Exists(ofd.InitialDirectory))
{ ofd.RestoreDirectory = false; ofd.FilterIndex = 1; ofd.FileName = ""; }
2016-02-01 07:15:54 +00:00
if (ofd.ShowDialog() == DialogResult.OK)
openQuick(ofd.FileName);
2014-06-28 21:22:05 +00:00
}
private void mainMenuSave(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (!verifiedPKM()) return;
PKM pk = preparePKM();
string pkx = pk.Extension;
string ekx = 'e' + pkx.Substring(1, pkx.Length - 1);
SaveFileDialog sfd = new SaveFileDialog
{
Filter = $"Decrypted PKM File|*.{pkx}" +
2016-08-29 05:21:55 +00:00
(SAV.Generation > 2 ? "" : $"|Encrypted PKM File|*.{ekx}") +
"|Binary File|*.bin" +
"|All Files|*.*",
DefaultExt = pkx,
FileName = Util.CleanFileName(pk.FileName)
};
if (sfd.ShowDialog() != DialogResult.OK) return;
string path = sfd.FileName;
string ext = Path.GetExtension(path);
2014-06-28 21:22:05 +00:00
if (File.Exists(path))
{
// File already exists, save a .bak
byte[] backupfile = File.ReadAllBytes(path);
File.WriteAllBytes(path + ".bak", backupfile);
}
2014-06-28 21:22:05 +00:00
if (new[] {".ekx", "."+ekx, ".bin"}.Contains(ext))
File.WriteAllBytes(path, pk.EncryptedPartyData);
else if (new[] { "."+pkx }.Contains(ext))
File.WriteAllBytes(path, pk.DecryptedBoxData);
else
{
Util.Error($"Foreign File Extension: {ext}", "Exporting as encrypted.");
File.WriteAllBytes(path, pkm.EncryptedPartyData);
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
}
private void mainMenuExit(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
if (ModifierKeys == Keys.Control) // Hotkey Triggered
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Quit PKHeX?")) return;
Close();
2014-12-13 22:48:34 +00:00
}
private void mainMenuAbout(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
// Open a new form with the About details.
new About().ShowDialog();
}
// Sub Menu Options
private void mainMenuBoxReport(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(frmReport)) as frmReport;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
2014-12-13 22:48:34 +00:00
frmReport ReportForm = new frmReport();
ReportForm.Show();
ReportForm.PopulateData(SAV.BoxData);
2014-12-13 22:48:34 +00:00
}
private void mainMenuDatabase(object sender, EventArgs e)
{
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(SAV_Database)) as SAV_Database;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
if (Directory.Exists(DatabasePath))
new SAV_Database(this).Show();
else
Util.Alert("PKHeX's database was not found.",
$"Please dump all boxes from a save file, then ensure the '{DatabasePath}' folder exists.");
}
private void mainMenuMysteryDM(object sender, EventArgs e)
{
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(SAV_MysteryGiftDB)) as SAV_MysteryGiftDB;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
new SAV_MysteryGiftDB(this).Show();
}
2014-12-13 22:48:34 +00:00
private void mainMenuUnicode(object sender, EventArgs e)
{
Properties.Settings.Default.Unicode = unicode = Menu_Unicode.Checked;
Properties.Settings.Default.Save();
updateUnicode();
2014-12-13 22:48:34 +00:00
}
private void mainMenuModifyDex(object sender, EventArgs e)
{
Properties.Settings.Default.SetUpdateDex = SaveFile.SetUpdateDex = Menu_ModifyDex.Checked;
Properties.Settings.Default.Save();
}
private void mainMenuModifyPKM(object sender, EventArgs e)
{
Properties.Settings.Default.SetUpdatePKM = SaveFile.SetUpdatePKM = Menu_ModifyPKM.Checked;
Properties.Settings.Default.Save();
}
private void mainMenuBoxLoad(object sender, EventArgs e)
{
string path = "";
if (Directory.Exists(DatabasePath))
{
DialogResult ld = Util.Prompt(MessageBoxButtons.YesNo, "Load from PKHeX's database?");
if (ld == DialogResult.Yes)
path = DatabasePath;
else if (ld == DialogResult.No)
{
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
path = fbd.SelectedPath;
}
else return;
}
else
{
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == DialogResult.OK)
path = fbd.SelectedPath;
}
loadBoxesFromDB(path);
}
private void mainMenuBoxDump(object sender, EventArgs e)
{
string path;
bool dumptoboxes = false;
// Dump all of box content to files.
DialogResult ld = Util.Prompt(MessageBoxButtons.YesNo, "Save to PKHeX's database?");
if (ld == DialogResult.Yes)
{
path = DatabasePath;
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
else if (ld == DialogResult.No)
{
dumptoboxes = DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Save each box separately?");
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() != DialogResult.OK)
return;
path = fbd.SelectedPath;
}
else return;
dumpBoxesToDB(path, dumptoboxes);
}
private void manMenuBatchEditor(object sender, EventArgs e)
{
new BatchEditor().ShowDialog();
setPKXBoxes(); // refresh
updateBoxViewers();
}
// Misc Options
private void clickShowdownImportPK6(object sender, EventArgs e)
{
2016-04-05 03:39:11 +00:00
if (!formInitialized)
return;
if (!Clipboard.ContainsText())
{ Util.Alert("Clipboard does not contain text."); return; }
// Get Simulator Data
ShowdownSet Set = new ShowdownSet(Clipboard.GetText());
if (Set.Species < 0)
{ Util.Alert("Set data not found in clipboard."); return; }
if (Set.Nickname != null && Set.Nickname.Length > SAV.NickLength)
Set.Nickname = Set.Nickname.Substring(0, SAV.NickLength);
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Import this set?", Set.getText()))
{ return; }
if (Set.InvalidLines.Any())
Util.Alert("Invalid lines detected:", string.Join(Environment.NewLine, Set.InvalidLines));
// Set Species & Nickname
CB_Species.SelectedValue = Set.Species;
CHK_Nicknamed.Checked = Set.Nickname != null;
if (Set.Nickname != null)
TB_Nickname.Text = Set.Nickname;
if (Set.Gender != null && PKX.getGender(Set.Gender) != 2 && PKX.getGender(Set.Gender) != 2)
{
int Gender = PKX.getGender(Set.Gender);
Label_Gender.Text = gendersymbols[Gender];
Label_Gender.ForeColor = Gender == 2 ? Label_Species.ForeColor : (Gender == 1 ? Color.Red : Color.Blue);
}
// Set Form
string[] formStrings = PKX.getFormList(Set.Species,
2016-03-15 00:54:30 +00:00
Util.getStringList("types", "en"),
Util.getStringList("forms", "en"), gendersymbols, SAV.Generation);
int form = 0;
for (int i = 0; i < formStrings.Length; i++)
if (formStrings[i].Contains(Set.Form ?? ""))
{ form = i; break; }
CB_Form.SelectedIndex = form;
// Set Ability
int[] abilities = SAV.Personal.getAbilities(Set.Species, form);
int ability = Array.IndexOf(abilities, Set.Ability);
if (ability < 0) ability = 0;
CB_Ability.SelectedIndex = ability;
ComboBox[] m = {CB_Move1, CB_Move2, CB_Move3, CB_Move4};
for (int i = 0; i < 4; i++) m[i].SelectedValue = Set.Moves[i];
// Set Item and Nature
CB_HeldItem.SelectedValue = Set.Item < 0 ? 0 : Set.Item;
CB_Nature.SelectedValue = Set.Nature < 0 ? 0 : Set.Nature;
// Set IVs
TB_HPIV.Text = Set.IVs[0].ToString();
TB_ATKIV.Text = Set.IVs[1].ToString();
TB_DEFIV.Text = Set.IVs[2].ToString();
TB_SPAIV.Text = Set.IVs[4].ToString();
TB_SPDIV.Text = Set.IVs[5].ToString();
TB_SPEIV.Text = Set.IVs[3].ToString();
// Set EVs
TB_HPEV.Text = Set.EVs[0].ToString();
TB_ATKEV.Text = Set.EVs[1].ToString();
TB_DEFEV.Text = Set.EVs[2].ToString();
TB_SPAEV.Text = Set.EVs[4].ToString();
TB_SPDEV.Text = Set.EVs[5].ToString();
TB_SPEEV.Text = Set.EVs[3].ToString();
// Set Level and Friendship
TB_Level.Text = Set.Level.ToString();
TB_Friendship.Text = Set.Friendship.ToString();
// Reset IV/EVs
BTN_RerollPID.PerformClick();
BTN_RerollEC.PerformClick();
ComboBox[] p = {CB_PPu1, CB_PPu2, CB_PPu3, CB_PPu4};
for (int i = 0; i < 4; i++)
p[i].SelectedIndex = m[i].SelectedIndex != 0 ? 3 : 0; // max PP
if (Set.Shiny) BTN_Shinytize.PerformClick();
pkm = preparePKM();
updateLegality();
}
private void clickShowdownExportPK6(object sender, EventArgs e)
{
if (!formInitialized)
return;
if (!verifiedPKM())
{ Util.Alert("Fix data before exporting."); return; }
Clipboard.SetText(preparePKM().ShowdownText);
Util.Alert("Exported Showdown Set to Clipboard:", Clipboard.GetText());
}
private void clickShowdownExportParty(object sender, EventArgs e)
{
if (SAV.PartyData.Length <= 0) return;
try
{
Clipboard.SetText(
SAV.PartyData.Aggregate("", (current, pk) => current + pk.ShowdownText
+ Environment.NewLine + Environment.NewLine).Trim());
Util.Alert("Showdown Team (Party) set to Clipboard.");
}
catch { }
}
private void clickShowdownExportBattleBox(object sender, EventArgs e)
{
if (SAV.BattleBoxData.Length <= 0) return;
try
{
Clipboard.SetText(
SAV.BattleBoxData.Aggregate("", (current, pk) => current + pk.ShowdownText
+ Environment.NewLine + Environment.NewLine).Trim());
Util.Alert("Showdown Team (Battle Box) set to Clipboard.");
}
catch { }
}
private void clickOpenTempFolder(object sender, EventArgs e)
{
string path = Util.GetTempFolder();
if (Directory.Exists(Path.Combine(path, "root")))
2016-07-17 17:06:52 +00:00
Process.Start("explorer.exe", Path.Combine(path, "root"));
else if (Directory.Exists(path))
2016-07-17 17:06:52 +00:00
Process.Start("explorer.exe", path);
else
Util.Alert("Can't find the temporary file.", "Make sure the Cyber Gadget software is paused.");
}
private void clickOpenCacheFolder(object sender, EventArgs e)
{
string path = Util.GetCacheFolder();
if (Directory.Exists(path))
2016-07-17 17:06:52 +00:00
Process.Start("explorer.exe", path);
else
Util.Alert("Can't find the cache folder.");
}
private void clickOpenSDFFolder(object sender, EventArgs e)
{
string path = Path.GetPathRoot(Util.get3DSLocation());
if (path != null && Directory.Exists(path = Path.Combine(path, "filer", "UserSaveData")))
2016-07-17 17:06:52 +00:00
Process.Start("explorer.exe", path);
else
Util.Alert("Can't find the SaveDataFiler folder.");
}
private void clickOpenSDBFolder(object sender, EventArgs e)
{
string path3DS = Path.GetPathRoot(Util.get3DSLocation());
string path;
if (path3DS != null && Directory.Exists(path = Path.Combine(path3DS, "SaveDataBackup")))
2016-07-17 17:06:52 +00:00
Process.Start("explorer.exe", path);
else
Util.Alert("Can't find the SaveDataBackup folder.");
}
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Main Menu Subfunctions
private void openQuick(string path, bool force = false)
2014-12-13 22:48:34 +00:00
{
if (!(CanFocus || force))
{
SystemSounds.Asterisk.Play();
return;
}
2014-12-13 22:48:34 +00:00
// detect if it is a folder (load into boxes or not)
if (Directory.Exists(path))
{ loadBoxesFromDB(path); return; }
2014-08-17 01:42:51 +00:00
2014-12-13 22:48:34 +00:00
string ext = Path.GetExtension(path);
FileInfo fi = new FileInfo(path);
if (fi.Length > 0x10009C && fi.Length != 0x380000)
2014-12-13 22:48:34 +00:00
Util.Error("Input file is too large.", path);
else
{
byte[] input; try { input = File.ReadAllBytes(path); }
2016-08-30 02:19:11 +00:00
catch (Exception e) { Util.Error("Unable to load file. It could be in use by another program.\nPath: " + path, e); return; }
2014-12-13 22:48:34 +00:00
try { openFile(input, path, ext); }
2016-08-30 02:19:11 +00:00
catch (Exception e) { Util.Error("Unable to load file.\nPath: " + path, e); }
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
}
private void openFile(byte[] input, string path, string ext)
{
MysteryGift tg; PKM temp; string c;
byte[] footer = new byte[0];
byte[] header = new byte[0];
2016-09-24 01:47:03 +00:00
SaveUtil.CheckHeaderFooter(ref input, ref header, ref footer);
2014-12-13 22:48:34 +00:00
#region Powersaves Read-Only Conversion
if (input.Length == 0x10009C) // Resize to 1MB
{
Array.Copy(input, 0x9C, input, 0, 0x100000);
Array.Resize(ref input, 0x100000);
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
// Verify the Data Input Size is Proper
if (input.Length == 0x100000)
2014-12-13 22:48:34 +00:00
{
if (openXOR(input, path)) // Check if we can load the save via xorpad
return; // only if a save is loaded we abort
if (BitConverter.ToUInt64(input, 0x10) != 0) // encrypted save
2016-02-09 23:44:59 +00:00
{ Util.Error("PKHeX only edits decrypted save files." + Environment.NewLine + "This save file is not decrypted.", path); return; }
DialogResult sdr = Util.Prompt(MessageBoxButtons.YesNoCancel, "Press Yes to load the sav at 0x3000", "Press No for the one at 0x82000");
if (sdr == DialogResult.Cancel)
return;
int savshift = sdr == DialogResult.Yes ? 0 : 0x7F000;
byte[] psdata = input.Skip(0x5400 + savshift).Take(SaveUtil.SIZE_G6ORAS).ToArray();
if (BitConverter.ToUInt32(psdata, psdata.Length - 0x1F0) != SaveUtil.BEEF)
Array.Resize(ref psdata, SaveUtil.SIZE_G6XY);
if (BitConverter.ToUInt32(psdata, psdata.Length - 0x1F0) != SaveUtil.BEEF)
2016-02-09 23:44:59 +00:00
{ Util.Error("The data file is not a valid save file", path); return; }
openSAV(psdata, path);
}
#endregion
#region SAV/PKM
else if (SaveUtil.getSAVGeneration(input) != -1)
2016-09-24 01:47:03 +00:00
{
openSAV(input, path);
SAV.Footer = footer;
SAV.Header = header;
}
else if ((temp = PKMConverter.getPKMfromBytes(input)) != null)
{
PKM pk = PKMConverter.convertToFormat(temp, SAV.PKMType, out c);
if (pk == null)
Util.Alert("Conversion failed.", c);
else if (SAV.Generation < 3 && (pk is PK1 ? ((PK1)pk).Japanese : ((PK2)pk).Japanese) != SAV.GetJapanese)
Util.Alert($"Cannot load {(SAV.GetJapanese ? "an International" : "a Japanese")} {pk.GetType().Name} in {(SAV.GetJapanese ? "a Japanese" : "an International")} save file.");
else
populateFields(pk);
Console.WriteLine(c);
}
#endregion
#region PC/Box Data
2016-09-14 16:00:58 +00:00
else if (BitConverter.ToUInt16(input, 4) == 0 && BitConverter.ToUInt32(input, 8) > 0 && PKX.getIsPKM(input.Length / SAV.BoxSlotCount / SAV.BoxCount) || PKX.getIsPKM(input.Length / SAV.BoxSlotCount))
2014-06-28 21:22:05 +00:00
{
if (SAV.setPCBin(input))
Util.Alert("PC Binary loaded.");
else if (SAV.setBoxBin(input, CB_BoxSelect.SelectedIndex))
Util.Alert("Box Binary loaded.");
2014-12-13 22:48:34 +00:00
else
{
Util.Alert("Binary is not compatible with save file.", "Current SAV Generation: " + SAV.Generation);
return;
}
2015-01-27 06:05:04 +00:00
setPKXBoxes();
updateBoxViewers();
}
2015-01-24 18:45:32 +00:00
#endregion
2015-02-24 07:52:32 +00:00
#region Battle Video
else if (input.Length == 0x2E60 && BitConverter.ToUInt64(input, 0xE18) != 0 && BitConverter.ToUInt16(input, 0xE12) == 0)
2015-02-24 07:52:32 +00:00
{
if (SAV.Generation != 6)
{ Util.Alert("Cannot load a Gen6 Battle Video to a past generation save file."); return; }
2016-08-14 13:30:18 +00:00
if (Util.Prompt(MessageBoxButtons.YesNo, "Load Battle Video Pokémon data to " + CB_BoxSelect.Text + "?", "The box will be overwritten.") != DialogResult.Yes)
return;
bool? noSetb = getPKMSetOverride();
int offset = SAV.getBoxOffset(CB_BoxSelect.SelectedIndex);
2015-02-24 07:52:32 +00:00
for (int i = 0; i < 24; i++)
{
byte[] data = input.Skip(0xE18 + PKX.SIZE_6PARTY * i + i / 6 * 8).Take(PKX.SIZE_6STORED).ToArray();
SAV.setStoredSlot(data, offset + i * SAV.SIZE_STORED, noSetb);
}
2015-02-24 07:52:32 +00:00
setPKXBoxes();
updateBoxViewers();
2015-02-24 07:52:32 +00:00
}
#endregion
#region Mystery Gift (Templates)
else if ((tg = MysteryGift.getMysteryGift(input, ext)) != null)
2015-12-27 00:05:26 +00:00
{
if (!tg.IsPokémon)
2015-12-27 00:05:26 +00:00
{
Util.Alert("Mystery Gift is not a Pokémon.", path);
2015-12-27 00:05:26 +00:00
return;
}
temp = tg.convertToPKM(SAV);
if (temp.Format == SAV.Generation && ModifierKeys == Keys.Control && SAV.HasWondercards)
2015-12-27 00:05:26 +00:00
{
B_OpenWondercards_Click(tg, null);
2015-12-27 00:05:26 +00:00
return;
}
PKM pk = PKMConverter.convertToFormat(temp, SAV.PKMType, out c);
if (pk == null)
Util.Alert("Conversion failed.", c);
else
populateFields(pk);
Console.WriteLine(c);
2015-12-27 00:05:26 +00:00
}
2015-04-01 00:58:23 +00:00
#endregion
2014-12-13 22:48:34 +00:00
else
Util.Error("Attempted to load an unsupported file type/size.",
$"File Loaded:{Environment.NewLine}{path}",
$"File Size:{Environment.NewLine}{input.Length} bytes (0x{input.Length.ToString("X4")})");
2014-12-13 22:48:34 +00:00
}
private bool openXOR(byte[] input, string path)
{
// Detection of stored Decryption XORpads:
if (ModifierKeys == Keys.Control) return false; // no xorpad compatible
byte[] savID = input.Take(0x10).ToArray();
string exepath = Application.StartupPath;
string xorpath = exepath.Clone().ToString();
string[] XORpads = Directory.GetFiles(xorpath);
int loop = 0;
check:
foreach (byte[] data in from file in XORpads let fi = new FileInfo(file) where (fi.Name.ToLower().Contains("xorpad") || fi.Name.ToLower().Contains("key")) && (fi.Length == 0x10009C || fi.Length == 0x100000) select File.ReadAllBytes(file))
{
// Fix xorpad alignment
byte[] xorpad = data;
if (xorpad.Length == 0x10009C) // Trim off Powersaves' header
xorpad = xorpad.Skip(0x9C).ToArray(); // returns 0x100000
if (!xorpad.Take(0x10).SequenceEqual(savID)) continue;
// Set up Decrypted File
byte[] decryptedPS = input.Skip(0x5400).Take(SaveUtil.SIZE_G6ORAS).ToArray();
// xor through and decrypt
for (int z = 0; z < decryptedPS.Length; z++)
decryptedPS[z] ^= xorpad[0x5400 + z];
// Weakly check the validity of the decrypted content
if (BitConverter.ToUInt32(decryptedPS, SaveUtil.SIZE_G6ORAS - 0x1F0) != SaveUtil.BEEF) // Not OR/AS
if (BitConverter.ToUInt32(decryptedPS, SaveUtil.SIZE_G6XY - 0x1F0) != SaveUtil.BEEF) // Not X/Y
continue;
else
Array.Resize(ref decryptedPS, SaveUtil.SIZE_G6XY); // set to X/Y size
else Array.Resize(ref decryptedPS, SaveUtil.SIZE_G6ORAS); // set to ORAS size just in case
// Save file is now decrypted!
// Trigger Loading of the decrypted save file.
openSAV(decryptedPS, path);
// Abort the opening of a non-cyber file.
return true;
}
// End file check loop, check the input path for xorpads too if it isn't the same as the EXE (quite common).
if (xorpath != exepath || loop++ > 0) return false; // no xorpad compatible
xorpath = Path.GetDirectoryName(path); goto check;
}
private void openSAV(byte[] input, string path)
2014-12-13 22:48:34 +00:00
{
SaveFile sav = SaveUtil.getVariantSAV(input);
if (sav == null || sav.Version == GameVersion.Invalid)
{ Util.Error("Invalid save file loaded. Aborting.", path); return; }
if (sav.Generation == 3) // Japanese Save files are different. Get isJapanese
2016-07-15 03:22:24 +00:00
{
if (sav.Version == GameVersion.Unknown)
{
// Hacky cheats invalidated the Game Code value.
var drGame = Util.Prompt(MessageBoxButtons.YesNoCancel,
"Unknown Gen3 Game Detected. Select Origins:",
"Yes: Ruby / Sapphire" + Environment.NewLine +
"No: Emerald" + Environment.NewLine +
"Cancel: FireRed / LeafGreen");
if (drGame == DialogResult.Yes)
sav = new SAV3(sav.BAK, GameVersion.RS);
else if (drGame == DialogResult.No)
sav = new SAV3(sav.BAK, GameVersion.E);
else
sav = new SAV3(sav.BAK, GameVersion.FRLG);
}
var drJP = Util.Prompt(MessageBoxButtons.YesNoCancel, $"Generation 3 ({sav.Version}) Save File detected. Select Origins:", "Yes: International" + Environment.NewLine + "No: Japanese");
if (drJP == DialogResult.Cancel)
2016-07-15 03:22:24 +00:00
return;
sav.Japanese = drJP == DialogResult.No;
if (sav.Version == GameVersion.FRLG)
{
var drFRLG = Util.Prompt(MessageBoxButtons.YesNoCancel, $"{sav.Version} detected. Select version...", "Yes: FireRed" + Environment.NewLine + "No: LeafGreen");
if (drFRLG == DialogResult.Cancel)
return;
sav.Personal = drFRLG == DialogResult.Yes ? PersonalTable.FR : PersonalTable.LG;
}
2016-07-15 03:22:24 +00:00
}
2016-08-11 04:40:09 +00:00
loadSAV(sav, path);
}
private void loadSAV(SaveFile sav, string path)
{
// clean fields
PKM pk = preparePKM();
populateFields(SAV.BlankPKM);
SAV = sav;
if (path != null) // Actual save file
{
SAV.FilePath = Path.GetDirectoryName(path);
SAV.FileName = Path.GetExtension(path) == ".bak"
? Path.GetFileName(path).Split(new[] { " [" }, StringSplitOptions.None)[0]
: Path.GetFileName(path);
Text = $"PKH{(HaX ? "a" : "e")}X - " + $"SAV{SAV.Generation}: {Path.GetFileNameWithoutExtension(Util.CleanFileName(SAV.BAKName))}"; // more descriptive
// If backup folder exists, save a backup.
string backupName = Path.Combine(BackupPath, Util.CleanFileName(SAV.BAKName));
if (SAV.Exportable && Directory.Exists(BackupPath) && !File.Exists(backupName))
File.WriteAllBytes(backupName, SAV.BAK);
GB_SAVtools.Visible = true;
}
else // Blank save file
{
SAV.FilePath = null;
SAV.FileName = "Blank Save File";
Text = $"PKH{(HaX ? "a" : "e")}X - " + $"SAV{SAV.Generation}: {SAV.FileName} [{SAV.OT} ({SAV.Version})]";
GB_SAVtools.Visible = false;
}
Menu_ExportSAV.Enabled = B_VerifyCHK.Enabled = SAV.Exportable;
2016-04-19 01:21:50 +00:00
// Close subforms that are save dependent
Type[] f = { typeof(SAV_BoxViewer), typeof(f2_Text) };
foreach (var form in Application.OpenForms.Cast<Form>().Where(form => f.Contains(form.GetType())).ToArray())
form.Close();
2014-12-13 22:48:34 +00:00
setBoxNames(); // Display the Box Names
if (SAV.HasBox)
{
int startBox = path == null ? 0 : SAV.CurrentBox; // FF if BattleBox
if (startBox > SAV.BoxCount - 1) { tabBoxMulti.SelectedIndex = 1; CB_BoxSelect.SelectedIndex = 0; }
else { tabBoxMulti.SelectedIndex = 0; CB_BoxSelect.SelectedIndex = startBox; }
}
setPKXBoxes(); // Reload all of the PKX Windows
2015-12-17 03:33:58 +00:00
bool WindowTranslationRequired = false;
// Hide content if not present in game.
GB_SUBE.Visible = SAV.HasSUBE;
PB_Locked.Visible = SAV.HasBattleBox && SAV.BattleBoxLocked;
if (!SAV.HasBox && tabBoxMulti.TabPages.Contains(Tab_Box))
tabBoxMulti.TabPages.Remove(Tab_Box);
else if (SAV.HasBox && !tabBoxMulti.TabPages.Contains(Tab_Box))
{
tabBoxMulti.TabPages.Insert(0, Tab_Box);
WindowTranslationRequired = true;
}
Menu_LoadBoxes.Enabled = Menu_DumpBoxes.Enabled = Menu_Report.Enabled = Menu_Modify.Enabled = B_SaveBoxBin.Enabled = SAV.HasBox;
int BoxTab = tabBoxMulti.TabPages.IndexOf(Tab_Box);
int PartyTab = tabBoxMulti.TabPages.IndexOf(Tab_PartyBattle);
if (!SAV.HasParty && tabBoxMulti.TabPages.Contains(Tab_PartyBattle))
tabBoxMulti.TabPages.Remove(Tab_PartyBattle);
else if (SAV.HasParty && !tabBoxMulti.TabPages.Contains(Tab_PartyBattle))
{
int index = BoxTab;
if (index < 0)
index = -1;
tabBoxMulti.TabPages.Insert(index + 1, Tab_PartyBattle);
WindowTranslationRequired = true;
}
if (!SAV.HasDaycare && tabBoxMulti.TabPages.Contains(Tab_Other))
tabBoxMulti.TabPages.Remove(Tab_Other);
else if (SAV.HasDaycare && !tabBoxMulti.TabPages.Contains(Tab_Other))
{
int index = PartyTab;
if (index < 0)
index = BoxTab;
if (index < 0)
index = -1;
tabBoxMulti.TabPages.Insert(index + 1, Tab_Other);
WindowTranslationRequired = true;
}
if (path != null) // Actual save file
{
PAN_BattleBox.Visible = L_BattleBox.Visible = L_ReadOnlyPBB.Visible = SAV.HasBattleBox;
GB_Daycare.Visible = SAV.HasDaycare;
GB_Fused.Visible = SAV.HasFused;
GB_GTS.Visible = SAV.HasGTS;
B_OpenSecretBase.Enabled = SAV.HasSecretBase;
B_OpenPokepuffs.Enabled = SAV.HasPuff;
B_OUTPasserby.Enabled = SAV.HasPSS;
B_OpenBoxLayout.Enabled = SAV.HasBoxWallpapers;
B_OpenWondercards.Enabled = SAV.HasWondercards;
B_OpenSuperTraining.Enabled = SAV.HasSuperTrain;
B_OpenHallofFame.Enabled = SAV.HasHoF;
B_OpenOPowers.Enabled = SAV.HasOPower;
B_OpenPokedex.Enabled = SAV.HasPokeDex;
B_OpenBerryField.Enabled = SAV.HasBerryField && SAV.XY;
B_OpenPokeblocks.Enabled = SAV.HasPokeBlock;
B_JPEG.Enabled = SAV.HasJPEG;
B_OpenEventFlags.Enabled = SAV.HasEvents;
B_OpenLinkInfo.Enabled = SAV.HasLink;
B_CGearSkin.Enabled = SAV.Generation == 5;
B_OpenTrainerInfo.Visible = B_OpenItemPouch.Visible = SAV.HasParty; // Box RS
}
GB_SAVtools.Visible = FLP_SAVtools.Controls.Cast<Control>().Any(c => c.Enabled);
foreach (Control c in FLP_SAVtools.Controls.Cast<Control>())
c.Visible = c.Enabled;
// Generational Interface
byte[] extraBytes = new byte[1];
2016-06-21 04:11:48 +00:00
Tip1.RemoveAll(); Tip2.RemoveAll(); Tip3.RemoveAll(); // TSV/PSV
FLP_Country.Visible = FLP_SubRegion.Visible = FLP_3DSRegion.Visible = SAV.Generation >= 6;
Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = SAV.Generation >= 6;
GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_Medals.Visible = BTN_History.Visible = SAV.Generation >= 6;
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = SAV.Generation >= 6;
PB_MarkPentagon.Visible = SAV.Generation == 6;
TB_GameSync.Visible = TB_Secure1.Visible = TB_Secure2.Visible = L_GameSync.Visible = L_Secure1.Visible = L_Secure2.Visible = SAV.Exportable && SAV.Generation == 6;
FLP_NSparkle.Visible = L_NSparkle.Visible = CHK_NSparkle.Visible = SAV.Generation == 5;
CB_Form.Visible = Label_Form.Visible = CHK_AsEgg.Visible = GB_EggConditions.Visible = PB_Mark5.Visible = PB_Mark6.Visible = SAV.Generation >= 4;
DEV_Ability.Enabled = DEV_Ability.Visible = SAV.Generation > 3 && HaX;
CB_Ability.Visible = !DEV_Ability.Enabled && SAV.Generation >= 3;
FLP_Nature.Visible = SAV.Generation >= 3;
FLP_Ability.Visible = SAV.Generation >= 3;
FLP_Language.Visible = SAV.Generation >= 3;
GB_ExtraBytes.Visible = GB_ExtraBytes.Enabled = SAV.Generation >= 3;
GB_Markings.Visible = SAV.Generation >= 3;
BTN_Ribbons.Visible = SAV.Generation >= 3;
CB_HPType.Enabled = CB_Form.Enabled = SAV.Generation >= 3;
BTN_RerollPID.Visible = Label_PID.Visible = TB_PID.Visible = Label_SID.Visible = TB_SID.Visible = SAV.Generation >= 3;
FLP_FriendshipForm.Visible = SAV.Generation >= 2;
FLP_HeldItem.Visible = SAV.Generation >= 2;
CHK_IsEgg.Visible = Label_Gender.Visible = SAV.Generation >= 2;
FLP_PKRS.Visible = FLP_EggPKRSRight.Visible = SAV.Generation >= 2;
Label_OTGender.Visible = SAV.Generation >= 2;
2016-08-29 05:21:55 +00:00
if (SAV.Generation == 1)
Label_IsShiny.Visible = false;
if (SAV.Version == GameVersion.BATREV)
{
L_SaveSlot.Visible = CB_SaveSlot.Visible = true;
CB_SaveSlot.Items.Clear();
CB_SaveSlot.DisplayMember = "Text"; CB_SaveSlot.ValueMember = "Value";
CB_SaveSlot.DataSource = new BindingSource(((SAV4BR) SAV).SaveSlots.Select(i => new ComboItem
{
Text = ((SAV4BR) SAV).SaveNames[i],
Value = i
}).ToList(), null);
CB_SaveSlot.SelectedValue = ((SAV4BR)SAV).CurrentSlot;
}
else
L_SaveSlot.Visible = CB_SaveSlot.Visible = false;
FLP_Purification.Visible = FLP_ShadowID.Visible = SAV.Version == GameVersion.COLO || SAV.Version == GameVersion.XD;
NUD_ShadowID.Maximum = SAV.MaxShadowID;
// HaX override, needs to be after DEV_Ability enabled assignment.
TB_AbilityNumber.Visible = SAV.Generation >= 6 && DEV_Ability.Enabled;
// Met Tab
FLP_MetDate.Visible = SAV.Generation >= 4;
FLP_Fateful.Visible = FLP_Ball.Visible = FLP_OriginGame.Visible = SAV.Generation >= 3;
FLP_MetLocation.Visible = FLP_MetLevel.Visible = SAV.Generation >= 2;
FLP_TimeOfDay.Visible = SAV.Generation == 2;
2016-08-29 05:21:55 +00:00
// Stats
FLP_StatsTotal.Visible = SAV.Generation >= 3;
FLP_Characteristic.Visible = SAV.Generation >= 3;
FLP_HPType.Visible = SAV.Generation >= 2;
2016-08-29 20:27:17 +00:00
PAN_Contest.Visible = SAV.Generation >= 3;
2016-08-29 05:21:55 +00:00
// Second daycare slot
SlotPictureBoxes[43].Visible = SAV.Generation >= 2;
2016-08-29 05:21:55 +00:00
2016-09-04 06:45:10 +00:00
if (sav.Generation == 1)
{
FLP_SpD.Visible = false;
Label_SPA.Visible = false;
Label_SPC.Visible = true;
TB_HPIV.Enabled = false;
MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV };
foreach (var ctrl in evControls)
{
ctrl.Mask = "00000";
ctrl.Size = Stat_HP.Size;
}
}
2016-09-04 06:45:10 +00:00
else if (sav.Generation == 2)
{
FLP_SpD.Visible = true;
Label_SPA.Visible = true;
Label_SPC.Visible = false;
TB_SPDEV.Enabled = TB_SPDIV.Enabled = false;
TB_HPIV.Enabled = false;
2016-09-04 06:45:10 +00:00
MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV };
foreach (var ctrl in evControls)
{
ctrl.Mask = "00000";
ctrl.Size = Stat_HP.Size;
2016-09-04 06:45:10 +00:00
}
}
else
{
FLP_SpD.Visible = true;
Label_SPA.Visible = true;
Label_SPC.Visible = false;
TB_SPDEV.Enabled = TB_SPDIV.Enabled = true;
TB_HPIV.Enabled = true;
MaskedTextBox[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV };
foreach (var ctrl in evControls)
{
ctrl.Mask = "000";
ctrl.Size = TB_ExtraByte.Size;
}
}
// Recenter PKM SubEditors
FLP_PKMEditors.Location = new Point((Tab_OTMisc.Width - FLP_PKMEditors.Width) / 2, FLP_PKMEditors.Location.Y);
switch (SAV.Generation)
{
case 1:
getFieldsfromPKM = populateFieldsPK1;
getPKMfromFields = preparePK1;
extraBytes = new byte[] {};
break;
case 2:
getFieldsfromPKM = populateFieldsPK2;
getPKMfromFields = preparePK2;
extraBytes = new byte[] { };
break;
case 3:
if (SAV.Version == GameVersion.COLO)
{
getFieldsfromPKM = populateFieldsCK3;
getPKMfromFields = prepareCK3;
extraBytes = CK3.ExtraBytes;
break;
}
if (SAV.Version == GameVersion.XD)
{
getFieldsfromPKM = populateFieldsXK3;
getPKMfromFields = prepareXK3;
extraBytes = XK3.ExtraBytes;
break;
}
getFieldsfromPKM = populateFieldsPK3;
getPKMfromFields = preparePK3;
extraBytes = PK3.ExtraBytes;
break;
case 4:
if (SAV.Version == GameVersion.BATREV)
{
getFieldsfromPKM = populateFieldsBK4;
getPKMfromFields = prepareBK4;
}
else
{
getFieldsfromPKM = populateFieldsPK4;
getPKMfromFields = preparePK4;
}
extraBytes = PK4.ExtraBytes;
break;
case 5:
getFieldsfromPKM = populateFieldsPK5;
getPKMfromFields = preparePK5;
extraBytes = PK5.ExtraBytes;
break;
case 6:
getFieldsfromPKM = populateFieldsPK6;
getPKMfromFields = preparePK6;
extraBytes = PK6.ExtraBytes;
2016-07-19 04:39:43 +00:00
SAV6 sav6 = (SAV6)SAV;
TB_GameSync.Enabled = sav6.GameSyncID != 0;
TB_GameSync.Text = sav6.GameSyncID.ToString("X16");
TB_Secure1.Text = sav6.Secure1.ToString("X16");
TB_Secure2.Text = sav6.Secure2.ToString("X16");
break;
}
bool init = fieldsInitialized;
fieldsInitialized = fieldsLoaded = false;
pkm = pkm.GetType() != SAV.PKMType ? SAV.BlankPKM : pk;
if (pkm.Format < 3)
pkm = SAV.BlankPKM;
populateFilteredDataSources();
populateFields(pkm);
fieldsInitialized |= init;
// SAV Specific Limits
TB_OT.MaxLength = SAV.OTLength;
TB_OTt2.MaxLength = SAV.OTLength;
TB_Nickname.MaxLength = SAV.NickLength;
// Hide Unused Tabs
if (SAV.Generation == 1 && tabMain.TabPages.Contains(Tab_Met))
tabMain.TabPages.Remove(Tab_Met);
else if (SAV.Generation != 1 && !tabMain.TabPages.Contains(Tab_Met))
{
tabMain.TabPages.Insert(1, Tab_Met);
WindowTranslationRequired = true;
}
// Common HaX Interface
CHK_HackedStats.Enabled = CHK_HackedStats.Visible = MT_Level.Enabled = MT_Level.Visible = MT_Form.Enabled = MT_Form.Visible = HaX;
TB_Level.Visible = !HaX;
// Load Extra Byte List
if (GB_ExtraBytes.Enabled)
{
CB_ExtraBytes.Items.Clear();
foreach (byte b in extraBytes)
CB_ExtraBytes.Items.Add("0x" + b.ToString("X2"));
CB_ExtraBytes.SelectedIndex = 0;
}
// pk2 save files do not have an Origin Game stored. Prompt the met location list to update.
if (SAV.Generation == 2)
updateOriginGame(null, null);
// Refresh PK#->PK6 conversion info
PKMConverter.updateConfig(SAV.SubRegion, SAV.Country, SAV.ConsoleRegion, SAV.OT, SAV.Gender);
if (WindowTranslationRequired) // force update -- re-added controls may be untranslated
Util.TranslateInterface(this, curlanguage);
// No changes made yet
UndoStack.Clear(); Menu_Undo.Enabled = false;
RedoStack.Clear(); Menu_Redo.Enabled = false;
// Indicate audibly the save is loaded
SystemSounds.Beep.Play();
2014-06-28 21:22:05 +00:00
}
private static void refreshWC6DB()
{
List<WC6> wc6db = new List<WC6>();
byte[] wc6bin = Properties.Resources.wc6;
for (int i = 0; i < wc6bin.Length; i += WC6.Size)
{
byte[] data = new byte[WC6.Size];
Array.Copy(wc6bin, i, data, 0, WC6.Size);
wc6db.Add(new WC6(data));
}
byte[] wc6full = Properties.Resources.wc6full;
for (int i = 0; i < wc6full.Length; i += WC6.SizeFull)
{
byte[] data = new byte[WC6.SizeFull];
Array.Copy(wc6full, i, data, 0, WC6.SizeFull);
wc6db.Add(new WC6(data));
}
if (Directory.Exists(WC6DatabasePath))
wc6db.AddRange(from file in Directory.GetFiles(WC6DatabasePath, "*", SearchOption.AllDirectories)
let fi = new FileInfo(file)
where new[] {".wc6full", ".wc6"}.Contains(fi.Extension) && new[] {WC6.Size, WC6.SizeFull}.Contains((int)fi.Length)
select new WC6(File.ReadAllBytes(file)));
Legal.WC6DB = wc6db.Distinct().ToArray();
}
2014-12-13 22:48:34 +00:00
// Language Translation
private void changeMainLanguage(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
PKM pk = SAV.getPKM((fieldsInitialized ? preparePKM() : pkm).Data);
bool alreadyInit = fieldsInitialized;
fieldsInitialized = false;
2014-12-13 22:48:34 +00:00
Menu_Options.DropDown.Close();
InitializeStrings();
InitializeLanguage();
string ProgramTitle = Text;
Util.TranslateInterface(this, curlanguage); // Translate the UI to language.
Text = ProgramTitle;
// Recenter PKM SubEditors
FLP_PKMEditors.Location = new Point((Tab_OTMisc.Width - FLP_PKMEditors.Width)/2, FLP_PKMEditors.Location.Y);
populateFields(pk); // put data back in form
2015-12-27 05:17:23 +00:00
fieldsInitialized |= alreadyInit;
// Set the culture (makes it easy to pass language to other forms)
Properties.Settings.Default.Language = curlanguage;
Properties.Settings.Default.Save();
Thread.CurrentThread.CurrentCulture = new CultureInfo(curlanguage);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
2014-12-13 22:48:34 +00:00
}
private void InitializeStrings()
{
if (CB_MainLanguage.SelectedIndex < 8)
curlanguage = lang_val[CB_MainLanguage.SelectedIndex];
2014-06-28 21:22:05 +00:00
string l = curlanguage;
2016-07-09 01:38:40 +00:00
// Past Generation strings
g3items = Util.getStringListFallback("ItemsG3", l, "en");
// XD and Colosseum
{
g3coloitems = (string[])g3items.Clone();
string[] tmp = Util.getStringListFallback("ItemsG3Colosseum", l, "en");
Array.Resize(ref g3coloitems, 500 + tmp.Length);
for (int i = g3items.Length; i < g3coloitems.Length; i++)
g3coloitems[i] = $"UNUSED {i}";
Array.Copy(tmp, 0, g3coloitems, g3coloitems.Length - tmp.Length, tmp.Length);
g3xditems = (string[])g3items.Clone();
string[] tmp2 = Util.getStringListFallback("ItemsG3XD", l, "en");
Array.Resize(ref g3xditems, 500 + tmp2.Length);
for (int i = g3items.Length; i < g3xditems.Length; i++)
g3xditems[i] = $"UNUSED {i}";
Array.Copy(tmp2, 0, g3xditems, g3xditems.Length - tmp2.Length, tmp2.Length);
}
g2items = Util.getStringListFallback("ItemsG2", l, "en");
g1items = Util.getStringListFallback("ItemsG1", l, "en");
metRSEFRLG_00000 = Util.getStringListFallback("rsefrlg_00000", l, "en");
metGSC_00000 = Util.getStringListFallback("gsc_00000", l, "en");
2016-07-09 01:38:40 +00:00
metCXD_00000 = Util.getStringListFallback("cxd_00000", l, "en");
// Sanitize a little
var metSanitize = (string[])metCXD_00000.Clone();
for (int i = 0; i < metSanitize.Length; i++)
if (metCXD_00000.Count(r => r == metSanitize[i]) > 1)
metSanitize[i] += $" [{i.ToString("000")}]";
metCXD_00000 = metSanitize;
2016-07-09 01:38:40 +00:00
// Current Generation strings
2016-03-15 00:54:30 +00:00
natures = Util.getStringList("natures", l);
types = Util.getStringList("types", l);
abilitylist = Util.getAbilitiesList(l);
movelist = Util.getMovesList(l);
2016-03-15 00:54:30 +00:00
itemlist = Util.getStringList("items", l);
characteristics = Util.getStringList("character", l);
specieslist = Util.getSpeciesList(l);
2016-03-15 00:54:30 +00:00
wallpapernames = Util.getStringList("wallpaper", l);
encountertypelist = Util.getStringList("encountertype", l);
gamelist = Util.getStringList("games", l);
gamelanguages = Util.getNulledStringArray(Util.getStringList("languages"));
balllist = new string[Legal.Items_Ball.Length];
for (int i = 0; i < balllist.Length; i++)
balllist[i] = itemlist[Legal.Items_Ball[i]];
if (l != "pt" || (l == "pt" && !fieldsInitialized)) // load initial binaries
2014-12-13 22:48:34 +00:00
{
2016-03-15 00:54:30 +00:00
pokeblocks = Util.getStringList("pokeblock", l);
forms = Util.getStringList("forms", l);
memories = Util.getStringList("memories", l);
genloc = Util.getStringList("genloc", l);
trainingbags = Util.getStringList("trainingbag", l);
trainingstage = Util.getStringList("supertraining", l);
puffs = Util.getStringList("puff", l);
2014-12-13 22:48:34 +00:00
}
2014-06-28 21:22:05 +00:00
// Gen4 Mail names not stored in future games. No clever solution like for HM's, so improvise.
for (int i = 137; i <= 148; i++)
itemlist[i] = $"Mail #{i-137+1} (G4)";
2014-12-13 22:48:34 +00:00
// Fix Item Names (Duplicate entries)
int len = itemlist[425].Length;
itemlist[426] = itemlist[425].Substring(0, len-1) + (char)(itemlist[425][len-1]+1) + " (G4)";
itemlist[427] = itemlist[425].Substring(0, len-1) + (char)(itemlist[425][len-1]+2) + " (G4)";
itemlist[456] += " (HG/SS)"; // S.S. Ticket
itemlist[736] += " (OR/AS)"; // S.S. Ticket
itemlist[463] += " (DPPt)"; // Storage Key
itemlist[734] += " (OR/AS)"; // Storage Key
itemlist[478] += " (HG/SS)"; // Basement Key
itemlist[478] += " (OR/AS)"; // Basement Key
itemlist[621] += " (M)"; // Xtransceiver
itemlist[626] += " (F)"; // Xtransceiver
2014-12-13 22:48:34 +00:00
itemlist[629] += " (2)"; // DNA Splicers
itemlist[637] += " (2)"; // Dropped Item
itemlist[707] += " (2)"; // Travel Trunk
itemlist[713] += " (2)"; // Alt Bike
itemlist[714] += " (2)"; // Holo Caster
itemlist[729] += " (1)"; // Meteorite
itemlist[740] += " (2)"; // Contest Costume
itemlist[751] += " (2)"; // Meteorite
itemlist[771] += " (3)"; // Meteorite
itemlist[772] += " (4)"; // Meteorite
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Get the Egg Name and then replace it with --- for the comboboxes.
eggname = specieslist[0];
specieslist[0] = "---";
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Get the met locations... for all of the games...
metHGSS_00000 = Util.getStringList("hgss_00000", l);
metHGSS_02000 = Util.getStringList("hgss_02000", l);
metHGSS_03000 = Util.getStringList("hgss_03000", l);
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
metBW2_00000 = Util.getStringList("bw2_00000", l);
metBW2_30000 = Util.getStringList("bw2_30000", l);
metBW2_40000 = Util.getStringList("bw2_40000", l);
metBW2_60000 = Util.getStringList("bw2_60000", l);
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
metXY_00000 = Util.getStringList("xy_00000", l);
metXY_30000 = Util.getStringList("xy_30000", l);
metXY_40000 = Util.getStringList("xy_40000", l);
metXY_60000 = Util.getStringList("xy_60000", l);
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Fix up some of the Location strings to make them more descriptive:
metHGSS_02000[1] += " (NPC)"; // Anything from an NPC
metHGSS_02000[2] += " (" + eggname + ")"; // Egg From Link Trade
metBW2_00000[36] = metBW2_00000[84] + "/" + metBW2_00000[36]; // Cold Storage in BW = PWT in BW2
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// BW2 Entries from 76 to 105 are for Entralink in BW
for (int i = 76; i < 106; i++)
metBW2_00000[i] = metBW2_00000[i] + "●";
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Localize the Poketransfer to the language (30001)
string[] ptransp = { "ポケシフター", "Poké Transfer", "Poké Fret", "Pokétrasporto", "Poképorter", "Pokétransfer", "포케시프터", "ポケシフター" };
metBW2_30000[1 - 1] = ptransp[Array.IndexOf(lang_val, curlanguage)];
2014-12-13 22:48:34 +00:00
metBW2_30000[2 - 1] += " (NPC)"; // Anything from an NPC
metBW2_30000[3 - 1] += " (" + eggname + ")"; // Egg From Link Trade
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Zorua/Zoroark events
metBW2_30000[10 - 1] = specieslist[251] + " (" + specieslist[570] + " 1)"; // Celebi's Zorua Event
metBW2_30000[11 - 1] = specieslist[251] + " (" + specieslist[570] + " 2)"; // Celebi's Zorua Event
metBW2_30000[12 - 1] = specieslist[571] + " (" + "1)"; // Zoroark
metBW2_30000[13 - 1] = specieslist[571] + " (" + "2)"; // Zoroark
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
metBW2_60000[3 - 1] += " (" + eggname + ")"; // Egg Treasure Hunter/Breeder, whatever...
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
metXY_00000[104] += " (X/Y)"; // Victory Road
metXY_00000[106] += " (X/Y)"; // Pokémon League
metXY_00000[202] += " (OR/AS)"; // Pokémon League
2014-12-13 22:48:34 +00:00
metXY_00000[298] += " (OR/AS)"; // Victory Road
metXY_30000[0] += " (NPC)"; // Anything from an NPC
metXY_30000[1] += " (" + eggname + ")"; // Egg From Link Trade
2014-11-30 01:47:17 +00:00
2014-12-13 22:48:34 +00:00
// Set the first entry of a met location to "" (nothing)
// Fix (None) tags
abilitylist[0] = itemlist[0] = movelist[0] = metXY_00000[0] = metBW2_00000[0] = metHGSS_00000[0] = "(" + itemlist[0] + ")";
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Force an update to the met locations
origintrack = GameVersion.Unknown;
2014-06-28 21:22:05 +00:00
// Update Legality Analysis strings
LegalityAnalysis.movelist = movelist;
if (fieldsInitialized)
2014-12-13 22:48:34 +00:00
updateIVs(null, null); // Prompt an update for the characteristics
}
#endregion
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
#region //// PKX WINDOW FUNCTIONS ////
private void InitializeFields()
{
// Now that the ComboBoxes are ready, load the data.
fieldsInitialized = true;
pkm.RefreshChecksum();
// Load Data
populateFields(pkm);
2014-06-28 21:22:05 +00:00
{
CB_Species.SelectedValue = 493;
CB_Move1.SelectedValue = 1;
2014-12-13 22:48:34 +00:00
TB_OT.Text = "PKHeX";
TB_TID.Text = 12345.ToString();
TB_SID.Text = 54321.ToString();
CB_GameOrigin.SelectedIndex = 0;
int curlang = Array.IndexOf(lang_val, curlanguage);
CB_Language.SelectedIndex = curlang > CB_Language.Items.Count - 1 ? 1 : curlang;
CB_BoxSelect.SelectedIndex = 0;
2014-12-13 22:48:34 +00:00
CB_Ball.SelectedIndex = 0;
CB_Country.SelectedIndex = 0;
2016-03-14 01:38:11 +00:00
CAL_MetDate.Value = CAL_EggDate.Value = DateTime.Today;
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
}
private void InitializeLanguage()
{
ComboBox[] cbs =
{
CB_Country, CB_SubRegion, CB_3DSReg, CB_Language, CB_Ball, CB_HeldItem, CB_Species, DEV_Ability,
CB_Nature, CB_EncounterType, CB_GameOrigin, CB_HPType
};
foreach (var cb in cbs) { cb.DisplayMember = "Text"; cb.ValueMember = "Value"; }
2014-12-14 18:31:53 +00:00
// Set the various ComboBox DataSources up with their allowed entries
2015-01-31 18:36:06 +00:00
setCountrySubRegion(CB_Country, "countries");
2014-12-14 18:31:53 +00:00
CB_3DSReg.DataSource = Util.getUnsortedCBList("regions3ds");
CB_Language.DataSource = Util.getUnsortedCBList("languages");
int[] ball_nums = { 7, 576, 13, 492, 497, 14, 495, 493, 496, 494, 11, 498, 8, 6, 12, 15, 9, 5, 499, 10, 1, 16 };
int[] ball_vals = { 7, 25, 13, 17, 22, 14, 20, 18, 21, 19, 11, 23, 8, 6, 12, 15, 9, 5, 24, 10, 1, 16 };
2016-02-10 08:33:42 +00:00
BallDataSource = Util.getVariedCBList(itemlist, ball_nums, ball_vals);
SpeciesDataSource = Util.getCBList(specieslist, null);
NatureDataSource = Util.getCBList(natures, null);
AbilityDataSource = Util.getCBList(abilitylist, null);
VersionDataSource = Util.getCBList(gamelist, Legal.Games_6oras, Legal.Games_6xy, Legal.Games_5, Legal.Games_4, Legal.Games_4e, Legal.Games_4r, Legal.Games_3, Legal.Games_3e, Legal.Games_3r, Legal.Games_3s);
MoveDataSource = Util.getCBList(movelist, null);
#region Met Locations
// Gen 2
{
var met_list = Util.getCBList(metGSC_00000, Enumerable.Range(0, 0x5F).ToArray());
met_list = Util.getOffsetCBList(met_list, metGSC_00000, 00000, new[] { 0x7E, 0x7F });
metGen2 = met_list;
}
// Gen 3
{
var met_list = Util.getCBList(metRSEFRLG_00000, Enumerable.Range(0, 213).ToArray());
met_list = Util.getOffsetCBList(met_list, metRSEFRLG_00000, 00000, new[] { 253, 254, 255 });
metGen3 = met_list;
var cxd_list = Util.getCBList(metCXD_00000, Enumerable.Range(0, metCXD_00000.Length).ToArray()).Where(c => c.Text.Length > 0).ToList();
metGen3CXD = cxd_list;
}
// Gen 4
{
var met_list = Util.getCBList(metHGSS_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2000 });
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, new[] { 2002 });
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, new[] { 3001 });
met_list = Util.getOffsetCBList(met_list, metHGSS_00000, 0000, Legal.Met_HGSS_0);
met_list = Util.getOffsetCBList(met_list, metHGSS_02000, 2000, Legal.Met_HGSS_2);
met_list = Util.getOffsetCBList(met_list, metHGSS_03000, 3000, Legal.Met_HGSS_3);
metGen4 = met_list;
}
// Gen 5
{
var met_list = Util.getCBList(metBW2_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, new[] { 30003 });
met_list = Util.getOffsetCBList(met_list, metBW2_00000, 00000, Legal.Met_BW2_0);
met_list = Util.getOffsetCBList(met_list, metBW2_30000, 30001, Legal.Met_BW2_3);
met_list = Util.getOffsetCBList(met_list, metBW2_40000, 40001, Legal.Met_BW2_4);
met_list = Util.getOffsetCBList(met_list, metBW2_60000, 60001, Legal.Met_BW2_6);
metGen5 = met_list;
}
// Gen 6
{
var met_list = Util.getCBList(metXY_00000, new[] { 0 });
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, new[] { 60002 });
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, new[] { 30002 });
met_list = Util.getOffsetCBList(met_list, metXY_00000, 00000, Legal.Met_XY_0);
met_list = Util.getOffsetCBList(met_list, metXY_30000, 30001, Legal.Met_XY_3);
met_list = Util.getOffsetCBList(met_list, metXY_40000, 40001, Legal.Met_XY_4);
met_list = Util.getOffsetCBList(met_list, metXY_60000, 60001, Legal.Met_XY_6);
metGen6 = met_list;
}
#endregion
CB_EncounterType.DataSource = Util.getCBList(encountertypelist, new[] { 0 }, Legal.Gen4EncounterTypes);
2015-12-14 15:52:25 +00:00
CB_HPType.DataSource = Util.getCBList(types.Skip(1).Take(16).ToArray(), null);
CB_Nature.DataSource = new BindingSource(NatureDataSource, null);
populateFilteredDataSources();
}
private void populateFilteredDataSources()
{
if (SAV.Generation > 1)
{
string[] items = itemlist;
if (SAV.Generation == 3)
{
switch (SAV.Version)
{
case GameVersion.COLO: items = g3coloitems; break;
case GameVersion.XD: items = g3xditems; break;
default: items = g3items; break;
}
}
if (SAV.Generation == 2)
items = g2items;
2016-07-09 01:38:40 +00:00
ItemDataSource = Util.getCBList(items, (HaX ? Enumerable.Range(0, SAV.MaxItemID) : SAV.HeldItems.Select(i => (int)i)).ToArray());
CB_HeldItem.DataSource = new BindingSource(ItemDataSource.Where(i => i.Value <= SAV.MaxItemID).ToList(), null);
}
CB_Ball.DataSource = new BindingSource(BallDataSource.Where(b => b.Value <= SAV.MaxBallID).ToList(), null);
CB_Species.DataSource = new BindingSource(SpeciesDataSource.Where(s => s.Value <= SAV.MaxSpeciesID).ToList(), null);
DEV_Ability.DataSource = new BindingSource(AbilityDataSource.Where(a => a.Value <= SAV.MaxAbilityID).ToList(), null);
CB_GameOrigin.DataSource = new BindingSource(VersionDataSource.Where(g => g.Value <= SAV.MaxGameID || SAV.Generation >= 3 && g.Value == 15).ToList(), null);
2015-03-09 00:41:13 +00:00
// Set the Move ComboBoxes too..
var moves = MoveDataSource.Where(m => m.Value <= SAV.MaxMoveID).ToList();
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4, CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 })
2014-06-28 21:22:05 +00:00
{
cb.DisplayMember = "Text"; cb.ValueMember = "Value";
cb.DataSource = new BindingSource(moves, null);
}
2014-06-28 21:22:05 +00:00
}
private Action getFieldsfromPKM;
private Func<PKM> getPKMfromFields;
public void populateFields(PKM pk, bool focus = true)
2014-06-28 21:22:05 +00:00
{
if (pk == null) { Util.Error("Attempted to load a null file."); return; }
if ((pk.Format >= 3 && pk.Format > SAV.Generation) // pk3-7, can't go backwards
|| (pk.Format <= 2 && SAV.Generation > 2 && SAV.Generation < 7)) // pk1-2, can't go 3-6
{ Util.Alert($"Can't load Gen{pk.Format} to Gen{SAV.Generation} games."); return; }
bool oldInit = fieldsInitialized;
fieldsInitialized = fieldsLoaded = false;
if (focus)
Tab_Main.Focus();
2014-12-13 22:48:34 +00:00
pkm = pk.Clone();
if (fieldsInitialized & !pkm.ChecksumValid)
Util.Alert("PKX File has an invalid checksum.");
if (pkm.Format != SAV.Generation) // past gen format
{
string c;
pkm = PKMConverter.convertToFormat(pkm, SAV.PKMType, out c);
if (pk.Format != pkm.Format && focus) // converted
Util.Alert("Converted File.");
}
try { getFieldsfromPKM(); }
catch { fieldsInitialized = oldInit; throw; }
CB_EncounterType.Visible = Label_EncounterType.Visible = pkm.Gen4;
fieldsInitialized = oldInit;
updateIVs(null, null);
updatePKRSInfected(null, null);
updatePKRSCured(null, null);
if (HaX)
{
MT_Level.Text = pkm.Stat_Level.ToString();
MT_Form.Text = pkm.AltForm.ToString();
if (pkm.Stat_HPMax != 0) // stats present
{
Stat_HP.Text = pkm.Stat_HPCurrent.ToString();
Stat_ATK.Text = pkm.Stat_ATK.ToString();
Stat_DEF.Text = pkm.Stat_DEF.ToString();
Stat_SPA.Text = pkm.Stat_SPA.ToString();
Stat_SPD.Text = pkm.Stat_SPD.ToString();
Stat_SPE.Text = pkm.Stat_SPE.ToString();
}
}
fieldsLoaded = true;
Label_HatchCounter.Visible = CHK_IsEgg.Checked && SAV.Generation > 1;
Label_Friendship.Visible = !CHK_IsEgg.Checked && SAV.Generation > 1;
// Set the Preview Box
dragout.Image = pk.Sprite;
updateLegality();
}
// General Use Functions shared by other Forms //
internal static void setCountrySubRegion(ComboBox CB, string type)
2014-06-28 21:22:05 +00:00
{
2015-01-31 23:59:23 +00:00
int index = CB.SelectedIndex;
// fix for Korean / Chinese being swapped
string cl = curlanguage + "";
cl = cl == "zh" ? "ko" : cl == "ko" ? "zh" : cl;
2014-06-28 21:22:05 +00:00
CB.DataSource = Util.getCBList(type, cl);
if (index > 0 && index < CB.Items.Count && fieldsInitialized)
2015-01-31 23:59:23 +00:00
CB.SelectedIndex = index;
2014-12-13 22:48:34 +00:00
}
private void setForms()
2014-12-13 22:48:34 +00:00
{
2016-07-28 01:20:15 +00:00
int species = Util.getIndex(CB_Species);
if (SAV.Generation < 4 && species != 201)
{
Label_Form.Visible = CB_Form.Visible = CB_Form.Enabled = false;
return;
}
bool hasForms = SAV.Personal[species].HasFormes || new[] { 201, 664, 665, 414 }.Contains(species);
CB_Form.Enabled = CB_Form.Visible = Label_Form.Visible = hasForms;
if (SAV.Generation == 2)
CB_Form.Enabled = false;
if (HaX)
Label_Form.Visible = true;
if (!hasForms)
return;
CB_Form.DataSource = PKX.getFormList(species, types, forms, gendersymbols, SAV.Generation).ToList();
2014-12-13 22:48:34 +00:00
}
private void setAbilityList()
{
if (SAV.Generation < 3) // no abilities
return;
int formnum = 0;
int species = Util.getIndex(CB_Species);
if (SAV.Generation > 3) // has forms
formnum = CB_Form.SelectedIndex;
2016-07-18 06:04:39 +00:00
int[] abils = SAV.Personal.getAbilities(species, formnum);
if (abils[1] == 0 && SAV.Generation != 3)
abils[1] = abils[0];
string[] abilIdentifier = {" (1)", " (2)", " (H)"};
List<string> ability_list = abils.Where(a => a != 0).Select((t, i) => abilitylist[t] + abilIdentifier[i]).ToList();
2016-07-05 06:53:35 +00:00
if (!ability_list.Any())
ability_list.Add(abilitylist[0] + abilIdentifier[0]);
int abil = CB_Ability.SelectedIndex;
CB_Ability.DataSource = ability_list;
CB_Ability.SelectedIndex = abil < 0 || abil >= CB_Ability.Items.Count ? 0 : abil;
}
// PKX Data Calculation Functions //
private void setIsShiny(object sender)
{
if (sender == TB_PID)
pkm.PID = Util.getHEXval(TB_PID.Text);
else if (sender == TB_TID)
pkm.TID = (int)Util.ToUInt32(TB_TID.Text);
else if (sender == TB_SID)
pkm.SID = (int)Util.ToUInt32(TB_SID.Text);
bool isShiny = pkm.IsShiny;
// Set the Controls
BTN_Shinytize.Visible = BTN_Shinytize.Enabled = !isShiny && SAV.Generation > 1;
2016-08-29 05:21:55 +00:00
Label_IsShiny.Visible = isShiny && SAV.Generation > 1;
// Refresh Markings (for Shiny Star if applicable)
setMarkings();
}
2014-12-13 22:48:34 +00:00
private void setMarkings()
{
PictureBox[] pba = { PB_Mark1, PB_Mark2, PB_Mark3, PB_Mark4, PB_Mark5, PB_Mark6 };
for (int i = 0; i < 6; i++)
pba[i].Image = Util.ChangeOpacity(pba[i].InitialImage, (pkm.Markings[i] ? 1 : 0) * 0.9 + 0.1);
PB_MarkShiny.Image = Util.ChangeOpacity(PB_MarkShiny.InitialImage, (!BTN_Shinytize.Enabled ? 1 : 0) * 0.9 + 0.1);
PB_MarkCured.Image = Util.ChangeOpacity(PB_MarkCured.InitialImage, (CHK_Cured.Checked ? 1 : 0) * 0.9 + 0.1);
2014-06-28 21:22:05 +00:00
int Version = Util.getIndex(CB_GameOrigin); // 24,25 = XY, 26,27 = ORAS, 28,29 = ???
PB_MarkPentagon.Image = Util.ChangeOpacity(PB_MarkPentagon.InitialImage, (Version >= 24 && Version <= 29 ? 1 : 0) * 0.9 + 0.1);
2014-12-13 22:48:34 +00:00
}
// Clicked Label Shortcuts //
private void clickQR(object sender, EventArgs e)
{
if (SAV.Generation != 6)
{
Util.Alert("QR feature only available for 6th Gen Games.");
return;
}
if (ModifierKeys == Keys.Alt)
{
// Fetch data from QR code...
byte[] ekx = QR.getQRData();
2015-03-14 02:59:51 +00:00
if (ekx == null) return;
if (ekx.Length != PKX.SIZE_6STORED) { Util.Alert($"Decoded data not {PKX.SIZE_6STORED} bytes.", $"QR Data Size: {ekx.Length}"); }
2015-03-14 02:59:51 +00:00
else try
{
PK6 pk = new PK6(PKX.decryptArray(ekx));
if (pk.ChecksumValid) { populateFields(pk); }
else Util.Alert("Invalid checksum in QR data.");
2015-03-14 02:59:51 +00:00
}
catch { Util.Alert("Error loading decrypted data."); }
2015-02-26 06:39:29 +00:00
}
else
2015-02-26 07:12:38 +00:00
{
if (!verifiedPKM()) return;
PKM pkx = preparePKM();
byte[] ekx = pkx.EncryptedBoxData;
const string server = "http://loadcode.projectpokemon.org/b1s1.html#"; // Rehosted with permission from LC/MS -- massive thanks!
Image qr = QR.getQRImage(ekx, server);
2015-03-14 02:59:51 +00:00
if (qr == null) return;
string[] r = pkx.QRText;
2015-03-14 02:59:51 +00:00
new QR(qr, dragout.Image, r[0], r[1], r[2], "PKHeX @ ProjectPokemon.org").ShowDialog();
2015-02-26 07:12:38 +00:00
}
}
2014-12-14 19:06:17 +00:00
private void clickFriendship(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
if (ModifierKeys == Keys.Control) // prompt to reset
TB_Friendship.Text = pkm.CurrentFriendship.ToString();
else
TB_Friendship.Text = TB_Friendship.Text == "255" ? SAV.Personal[pkm.Species].BaseFriendship.ToString() : "255";
2014-12-13 22:48:34 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickGender(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
if (SAV.Generation == 2)
return;
2014-12-13 22:48:34 +00:00
// Get Gender Threshold
2016-07-18 06:04:39 +00:00
int gt = SAV.Personal[Util.getIndex(CB_Species)].Gender;
2014-12-13 22:48:34 +00:00
if (gt == 255 || gt == 0 || gt == 254) // Single gender/genderless
return;
if (gt >= 255) return;
// If not a single gender(less) species: (should be <254 but whatever, 255 never happens)
2016-07-29 05:54:29 +00:00
int newGender = PKX.getGender(Label_Gender.Text) ^ 1;
if (SAV.Generation <= 4)
{
pkm.Species = Util.getIndex(CB_Species);
pkm.Version = Util.getIndex(CB_GameOrigin);
pkm.Nature = Util.getIndex(CB_Nature);
2016-07-29 05:54:29 +00:00
pkm.AltForm = CB_Form.SelectedIndex;
pkm.setPIDGender(newGender);
TB_PID.Text = pkm.PID.ToString("X8");
}
pkm.Gender = newGender;
Label_Gender.Text = gendersymbols[pkm.Gender];
Label_Gender.ForeColor = pkm.Gender == 2 ? Label_Species.ForeColor : (pkm.Gender == 1 ? Color.Red : Color.Blue);
2014-12-13 22:48:34 +00:00
if (PKX.getGender(CB_Form.Text) < 2) // Gendered Forms
CB_Form.SelectedIndex = PKX.getGender(Label_Gender.Text);
getQuickFiller(dragout);
2014-12-13 22:48:34 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickPPUps(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
CB_PPu1.SelectedIndex = ModifierKeys != Keys.Control && Util.getIndex(CB_Move1) > 0 ? 3 : 0;
CB_PPu2.SelectedIndex = ModifierKeys != Keys.Control && Util.getIndex(CB_Move2) > 0 ? 3 : 0;
CB_PPu3.SelectedIndex = ModifierKeys != Keys.Control && Util.getIndex(CB_Move3) > 0 ? 3 : 0;
CB_PPu4.SelectedIndex = ModifierKeys != Keys.Control && Util.getIndex(CB_Move4) > 0 ? 3 : 0;
2014-12-13 22:48:34 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickMarking(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
PictureBox[] pba = { PB_Mark1, PB_Mark2, PB_Mark3, PB_Mark4, PB_Mark5, PB_Mark6 };
int index = Array.IndexOf(pba, sender);
bool[] markings = pkm.Markings;
markings[index] ^= true;
pkm.Markings = markings;
2014-12-13 22:48:34 +00:00
setMarkings();
}
private void clickStatLabel(object sender, MouseEventArgs e)
{
if (!(ModifierKeys == Keys.Control || ModifierKeys == Keys.Alt))
return;
if (sender == Label_SPC)
sender = Label_SPA;
int index = Array.IndexOf(new[] { Label_HP, Label_ATK, Label_DEF, Label_SPA, Label_SPD, Label_SPE }, sender);
if (ModifierKeys == Keys.Alt) // EV
{
var mt = new[] {TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPAEV, TB_SPDEV, TB_SPEEV}[index];
if (e.Button == MouseButtons.Left) // max
mt.Text = SAV.Generation >= 3
? Math.Min(Math.Max(510 - Util.ToInt32(TB_EVTotal.Text) + Util.ToInt32(mt.Text), 0), 252).ToString()
: ushort.MaxValue.ToString();
else // min
mt.Text = 0.ToString();
}
else
new[] {TB_HPIV, TB_ATKIV, TB_DEFIV, TB_SPAIV, TB_SPDIV, TB_SPEIV}[index].Text =
(e.Button == MouseButtons.Left ? SAV.MaxIV : 0).ToString();
}
private void clickIV(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Control)
((MaskedTextBox) sender).Text = SAV.MaxIV.ToString();
else if (ModifierKeys == Keys.Alt)
((MaskedTextBox) sender).Text = 0.ToString();
}
private void clickEV(object sender, EventArgs e)
{
MaskedTextBox mt = (MaskedTextBox)sender;
if (ModifierKeys == Keys.Control) // EV
mt.Text = SAV.Generation >= 3
? Math.Min(Math.Max(510 - Util.ToInt32(TB_EVTotal.Text) + Util.ToInt32(mt.Text), 0), 252).ToString()
: ushort.MaxValue.ToString();
else if (ModifierKeys == Keys.Alt)
mt.Text = 0.ToString();
}
2014-12-14 19:06:17 +00:00
private void clickOT(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
if (!SAV.Exportable)
return;
// Get Save Information
TB_OT.Text = SAV.OT;
Label_OTGender.Text = gendersymbols[SAV.Gender % 2];
Label_OTGender.ForeColor = SAV.Gender == 1 ? Color.Red : Color.Blue;
TB_TID.Text = SAV.TID.ToString();
TB_SID.Text = SAV.SID.ToString();
if (SAV.Game >= 0)
CB_GameOrigin.SelectedValue = SAV.Game;
if (SAV.Language >= 0)
CB_Language.SelectedValue = SAV.Language;
if (SAV.HasGeolocation)
{
CB_SubRegion.SelectedValue = SAV.SubRegion;
CB_Country.SelectedValue = SAV.Country;
CB_3DSReg.SelectedValue = SAV.ConsoleRegion;
}
updateNickname(null, null);
2014-12-13 22:48:34 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickCT(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
if (TB_OTt2.Text.Length > 0)
Label_CTGender.Text = gendersymbols[SAV.Gender % 2];
}
private void clickGT(object sender, EventArgs e)
{
if (!GB_nOT.Visible)
return;
if (sender == GB_OT)
{
pkm.CurrentHandler = 0;
GB_OT.BackgroundImage = mixedHighlight;
GB_nOT.BackgroundImage = null;
}
else if (TB_OTt2.Text.Length > 0)
{
pkm.CurrentHandler = 1;
GB_OT.BackgroundImage = null;
GB_nOT.BackgroundImage = mixedHighlight;
}
TB_Friendship.Text = pkm.CurrentFriendship.ToString();
2014-12-13 22:48:34 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickTRGender(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
Label lbl = sender as Label;
2016-02-03 04:05:46 +00:00
if (!string.IsNullOrWhiteSpace(lbl?.Text)) // set gender label (toggle M/F)
{
int gender = PKX.getGender(lbl.Text) ^ 1;
lbl.Text = gendersymbols[gender];
lbl.ForeColor = gender == 1 ? Color.Red : Color.Blue;
}
2014-12-13 22:48:34 +00:00
}
private void clickMoves(object sender, EventArgs e)
{
updateLegality();
int[] m = Legality.getSuggestedRelearn();
string r = string.Join(Environment.NewLine, m.Select(v => v >= movelist.Length ? "ERROR" : movelist[v]));
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Apply suggested relearn moves?", r))
return;
CB_RelearnMove1.SelectedValue = m[0];
CB_RelearnMove2.SelectedValue = m[1];
CB_RelearnMove3.SelectedValue = m[2];
CB_RelearnMove4.SelectedValue = m[3];
updateLegality();
}
2014-12-13 22:48:34 +00:00
// Prompted Updates of PKX Functions //
private bool changingFields;
2014-12-13 22:48:34 +00:00
private void updateEXPLevel(object sender, EventArgs e)
{
2015-03-09 00:41:13 +00:00
if (changingFields) return;
changingFields = true;
if (sender == TB_EXP)
2014-12-13 22:48:34 +00:00
{
// Change the Level
uint EXP = Util.ToUInt32(TB_EXP.Text);
int Species = Util.getIndex(CB_Species);
int Level = PKX.getLevel(Species, EXP);
if (Level == 100)
EXP = PKX.getEXP(100, Species);
TB_Level.Text = Level.ToString();
if (!MT_Level.Visible)
TB_EXP.Text = EXP.ToString();
else
MT_Level.Text = Level.ToString();
2014-12-13 22:48:34 +00:00
}
else
2014-12-13 22:48:34 +00:00
{
// Change the XP
int Level = Util.ToInt32((MT_Level.Focused ? MT_Level : TB_Level).Text);
if (Level > 100) TB_Level.Text = "100";
if (Level > byte.MaxValue) MT_Level.Text = "255";
2014-12-13 22:48:34 +00:00
TB_EXP.Text = PKX.getEXP(Level, Util.getIndex(CB_Species)).ToString();
2014-12-13 22:48:34 +00:00
}
2015-03-09 00:41:13 +00:00
changingFields = false;
if (fieldsLoaded)
{
pkm.EXP = Util.ToUInt32(TB_EXP.Text);
if (SAV.Generation < 3)
pkm.Stat_Level = Util.ToInt32(TB_Level.Text);
}
2014-12-13 22:48:34 +00:00
updateStats();
updateLegality();
2014-12-13 22:48:34 +00:00
}
2015-03-09 00:41:13 +00:00
private void updateHPType(object sender, EventArgs e)
{
if (changingFields || !fieldsInitialized) return;
2015-03-09 00:41:13 +00:00
changingFields = true;
int[] ivs =
{
Util.ToInt32(TB_HPIV.Text), Util.ToInt32(TB_ATKIV.Text), Util.ToInt32(TB_DEFIV.Text),
Util.ToInt32(TB_SPAIV.Text), Util.ToInt32(TB_SPDIV.Text), Util.ToInt32(TB_SPEIV.Text)
};
2015-03-09 00:41:13 +00:00
// Change IVs to match the new Hidden Power
int[] newIVs = PKX.setHPIVs(Util.getIndex(CB_HPType), ivs);
TB_HPIV.Text = newIVs[0].ToString();
TB_ATKIV.Text = newIVs[1].ToString();
TB_DEFIV.Text = newIVs[2].ToString();
TB_SPAIV.Text = newIVs[3].ToString();
TB_SPDIV.Text = newIVs[4].ToString();
TB_SPEIV.Text = newIVs[5].ToString();
// Refresh View
2015-03-09 00:41:13 +00:00
changingFields = false;
updateIVs(null, null);
}
2014-12-13 22:48:34 +00:00
private void updateIVs(object sender, EventArgs e)
{
if (changingFields || !fieldsInitialized) return;
if (sender != null && Util.ToInt32(((MaskedTextBox) sender).Text) > SAV.MaxIV)
((MaskedTextBox) sender).Text = SAV.MaxIV.ToString("00");
2014-06-28 21:22:05 +00:00
2015-03-09 00:41:13 +00:00
changingFields = true;
2014-06-28 21:22:05 +00:00
// Update IVs
pkm.IV_HP = Util.ToInt32(TB_HPIV.Text);
pkm.IV_ATK = Util.ToInt32(TB_ATKIV.Text);
pkm.IV_DEF = Util.ToInt32(TB_DEFIV.Text);
pkm.IV_SPE = Util.ToInt32(TB_SPEIV.Text);
pkm.IV_SPA = Util.ToInt32(TB_SPAIV.Text);
pkm.IV_SPD = Util.ToInt32(TB_SPDIV.Text);
if (SAV.Generation < 3)
{
TB_HPIV.Text = pkm.IV_HP.ToString();
2016-09-04 06:45:10 +00:00
TB_SPDIV.Text = TB_SPAIV.Text;
if (SAV.Generation == 2)
{
Label_Gender.Text = gendersymbols[pkm.Gender];
Label_Gender.ForeColor = pkm.Gender == 2
? Label_Species.ForeColor
: (pkm.Gender == 1 ? Color.Red : Color.Blue);
CB_Form.SelectedIndex = pkm.AltForm;
setIsShiny(null);
getQuickFiller(dragout);
}
}
CB_HPType.SelectedValue = pkm.HPType;
changingFields = false;
2014-06-28 21:22:05 +00:00
// Potential Reading
L_Potential.Text = (!unicode
? new[] {"★☆☆☆", "★★☆☆", "★★★☆", "★★★★"}
: new[] {"+", "++", "+++", "++++"}
)[pkm.PotentialRating];
TB_IVTotal.Text = pkm.IVs.Sum().ToString();
2014-06-28 21:22:05 +00:00
int characteristic = pkm.Characteristic;
L_Characteristic.Visible = Label_CharacteristicPrefix.Visible = characteristic > -1;
if (characteristic > -1)
L_Characteristic.Text = characteristics[pkm.Characteristic];
2014-12-13 22:48:34 +00:00
updateStats();
}
private void updateEVs(object sender, EventArgs e)
{
if (sender is MaskedTextBox)
{
MaskedTextBox m = (MaskedTextBox)sender;
if (Util.ToInt32(m.Text) > SAV.MaxEV)
{ m.Text = SAV.MaxEV.ToString(); return; } // recursive on text set
}
2014-12-13 22:48:34 +00:00
changingFields = true;
if (sender == TB_HPEV) pkm.EV_HP = Util.ToInt32(TB_HPEV.Text);
else if (sender == TB_ATKEV) pkm.EV_ATK = Util.ToInt32(TB_ATKEV.Text);
else if (sender == TB_DEFEV) pkm.EV_DEF = Util.ToInt32(TB_DEFEV.Text);
else if (sender == TB_SPEEV) pkm.EV_SPE = Util.ToInt32(TB_SPEEV.Text);
else if (sender == TB_SPAEV) pkm.EV_SPA = Util.ToInt32(TB_SPAEV.Text);
else if (sender == TB_SPDEV) pkm.EV_SPD = Util.ToInt32(TB_SPDEV.Text);
2014-12-13 22:48:34 +00:00
2016-09-04 06:45:10 +00:00
if (SAV.Generation < 3)
TB_SPDEV.Text = TB_SPAEV.Text;
int evtotal = pkm.EVs.Sum();
2014-12-13 22:48:34 +00:00
if (evtotal > 510) // Background turns Red
TB_EVTotal.BackColor = Color.Red;
2014-12-13 22:48:34 +00:00
else if (evtotal == 510) // Maximum EVs
TB_EVTotal.BackColor = Color.Honeydew;
else if (evtotal == 508) // Fishy EVs
TB_EVTotal.BackColor = Color.LightYellow;
else TB_EVTotal.BackColor = TB_IVTotal.BackColor;
2014-12-13 22:48:34 +00:00
TB_EVTotal.Text = evtotal.ToString();
changingFields = false;
2014-12-13 22:48:34 +00:00
updateStats();
}
private void updateRandomIVs(object sender, EventArgs e)
{
changingFields = true;
if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift)
2014-12-13 22:48:34 +00:00
{
// Max IVs
TB_HPIV.Text = SAV.MaxIV.ToString();
TB_ATKIV.Text = SAV.MaxIV.ToString();
TB_DEFIV.Text = SAV.MaxIV.ToString();
TB_SPAIV.Text = SAV.MaxIV.ToString();
TB_SPDIV.Text = SAV.MaxIV.ToString();
TB_SPEIV.Text = SAV.MaxIV.ToString();
2014-12-13 22:48:34 +00:00
}
else
{
TB_HPIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
TB_ATKIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
TB_DEFIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
TB_SPAIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
TB_SPDIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
TB_SPEIV.Text = (Util.rnd32() & SAV.MaxIV).ToString();
2014-12-13 22:48:34 +00:00
}
changingFields = false;
updateIVs(null, null);
2014-12-13 22:48:34 +00:00
}
private void updateRandomEVs(object sender, EventArgs e)
{
2016-08-29 05:21:55 +00:00
changingFields = true;
if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift)
2014-12-13 22:48:34 +00:00
{
// Max EVs
2014-12-13 22:48:34 +00:00
TB_HPEV.Text = 0.ToString();
TB_ATKEV.Text = 0.ToString();
TB_DEFEV.Text = 0.ToString();
TB_SPAEV.Text = 0.ToString();
TB_SPDEV.Text = 0.ToString();
TB_SPEEV.Text = 0.ToString();
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
else
{
var evs = PKX.getRandomEVs(SAV.Generation);
2014-12-13 22:48:34 +00:00
TB_HPEV.Text = evs[0].ToString();
TB_ATKEV.Text = evs[1].ToString();
TB_DEFEV.Text = evs[2].ToString();
TB_SPAEV.Text = evs[3].ToString();
TB_SPDEV.Text = evs[4].ToString();
TB_SPEEV.Text = evs[5].ToString();
}
2016-08-29 05:21:55 +00:00
changingFields = false;
updateEVs(null, null);
2014-12-13 22:48:34 +00:00
}
private void updateRandomPID(object sender, EventArgs e)
{
if (fieldsLoaded)
{
pkm.Version = Util.getIndex(CB_GameOrigin);
pkm.PID = Util.getHEXval(TB_PID.Text);
pkm.Species = Util.getIndex(CB_Species);
pkm.Nature = Util.getIndex(CB_Nature);
pkm.AltForm = CB_Form.SelectedIndex;
}
if (sender == Label_Gender)
pkm.setPIDGender(pkm.Gender);
else if (sender == CB_Nature && pkm.Nature != Util.getIndex(CB_Nature))
pkm.setPIDNature(Util.getIndex(CB_Nature));
else if (sender == BTN_RerollPID)
pkm.setPIDGender(pkm.Gender);
else if (sender == CB_Ability && CB_Ability.SelectedIndex != pkm.PIDAbility && pkm.PIDAbility > -1)
pkm.PID = PKX.getRandomPID(pkm.Species, pkm.Gender, pkm.Version, pkm.Nature, pkm.Format, (uint)(CB_Ability.SelectedIndex * 0x10001));
TB_PID.Text = pkm.PID.ToString("X8");
getQuickFiller(dragout);
2016-08-09 01:42:42 +00:00
if (pkm.GenNumber < 6 && TB_EC.Visible)
TB_EC.Text = TB_PID.Text;
2014-12-13 22:48:34 +00:00
}
private void updateRandomEC(object sender, EventArgs e)
{
2016-08-09 01:42:42 +00:00
pkm.Version = Util.getIndex(CB_GameOrigin);
if (pkm.GenNumber < 6)
{
TB_EC.Text = TB_PID.Text;
Util.Alert("EC should match PID.");
}
int wIndex = Array.IndexOf(Legal.WurmpleFamily, Util.getIndex(CB_Species));
if (wIndex < 0)
{
TB_EC.Text = Util.rnd32().ToString("X8");
}
else
{
uint EC;
do { EC = Util.rnd32(); } while ((EC >> 16)%10/5 != wIndex/2);
TB_EC.Text = EC.ToString("X8");
}
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateHackedStats(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
Stat_HP.Enabled =
Stat_ATK.Enabled =
Stat_DEF.Enabled =
Stat_SPA.Enabled =
Stat_SPD.Enabled =
Stat_SPE.Enabled = CHK_HackedStats.Checked;
2014-06-28 21:22:05 +00:00
}
private void updateHackedStatText(object sender, EventArgs e)
{
if (!CHK_HackedStats.Checked || !(sender is TextBox))
return;
string text = ((TextBox)sender).Text;
2016-01-27 05:04:17 +00:00
if (string.IsNullOrWhiteSpace(text))
((TextBox)sender).Text = "0";
if (Convert.ToUInt32(text) > ushort.MaxValue)
((TextBox)sender).Text = "65535";
}
2014-12-13 22:48:34 +00:00
private void update255_MTB(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (Util.ToInt32(((MaskedTextBox) sender).Text) > byte.MaxValue)
((MaskedTextBox) sender).Text = "255";
}
2014-12-13 22:48:34 +00:00
private void updateForm(object sender, EventArgs e)
2014-12-12 05:44:05 +00:00
{
2016-07-28 02:25:36 +00:00
if (CB_Form == sender && fieldsLoaded)
pkm.AltForm = CB_Form.SelectedIndex;
2014-12-13 22:48:34 +00:00
updateStats();
// Repopulate Abilities if Species Form has different abilities
setAbilityList();
2014-12-13 22:48:34 +00:00
// Gender Forms
2016-07-28 01:20:15 +00:00
if (Util.getIndex(CB_Species) == 201)
{
if (fieldsLoaded && SAV.Generation == 3)
{
pkm.setPIDUnown3(CB_Form.SelectedIndex);
TB_PID.Text = pkm.PID.ToString("X8");
}
2016-07-28 01:20:15 +00:00
}
else if (PKX.getGender(CB_Form.Text) < 2)
2014-12-13 22:48:34 +00:00
Label_Gender.Text = CB_Form.Text;
if (changingFields)
return;
changingFields = true;
MT_Form.Text = CB_Form.SelectedIndex.ToString();
changingFields = false;
}
private void updateHaXForm(object sender, EventArgs e)
{
if (changingFields)
return;
changingFields = true;
int form = pkm.AltForm = Util.ToInt32(MT_Form.Text);
CB_Form.SelectedIndex = CB_Form.Items.Count > form ? form : -1;
changingFields = false;
2014-12-12 05:44:05 +00:00
}
2014-12-13 22:48:34 +00:00
private void updatePP(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
TB_PP1.Text = pkm.getMovePP(Util.getIndex(CB_Move1), CB_PPu1.SelectedIndex).ToString();
TB_PP2.Text = pkm.getMovePP(Util.getIndex(CB_Move2), CB_PPu2.SelectedIndex).ToString();
TB_PP3.Text = pkm.getMovePP(Util.getIndex(CB_Move3), CB_PPu3.SelectedIndex).ToString();
TB_PP4.Text = pkm.getMovePP(Util.getIndex(CB_Move4), CB_PPu4.SelectedIndex).ToString();
2014-12-13 22:48:34 +00:00
}
private void updatePKRSstrain(object sender, EventArgs e)
{
2015-03-14 02:59:51 +00:00
// Change the PKRS Days to the legal bounds.
int currentDuration = CB_PKRSDays.SelectedIndex;
CB_PKRSDays.Items.Clear();
foreach (int day in Enumerable.Range(0, CB_PKRSStrain.SelectedIndex % 4 + 2)) CB_PKRSDays.Items.Add(day);
2015-03-14 02:59:51 +00:00
// Set the days back if they're legal, else set it to 1. (0 always passes).
CB_PKRSDays.SelectedIndex = currentDuration < CB_PKRSDays.Items.Count ? currentDuration : 1;
2015-03-14 02:59:51 +00:00
if (CB_PKRSStrain.SelectedIndex != 0) return;
2015-03-14 02:59:51 +00:00
// Never Infected
CB_PKRSDays.SelectedIndex = 0;
CHK_Cured.Checked = false;
CHK_Infected.Checked = false;
}
private void updatePKRSdays(object sender, EventArgs e)
{
if (CB_PKRSDays.SelectedIndex != 0) return;
// If no days are selected
2014-12-13 22:48:34 +00:00
if (CB_PKRSStrain.SelectedIndex == 0)
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
// Never Infected
CHK_Cured.Checked = false;
CHK_Infected.Checked = false;
2014-06-28 21:22:05 +00:00
}
else CHK_Cured.Checked = true;
2014-06-28 21:22:05 +00:00
}
private void updatePKRSCured(object sender, EventArgs e)
{
if (!fieldsInitialized) return;
// Cured PokeRus is toggled
if (CHK_Cured.Checked)
{
// Has Had PokeRus
Label_PKRSdays.Visible = CB_PKRSDays.Visible = false;
CB_PKRSDays.SelectedIndex = 0;
Label_PKRS.Visible = CB_PKRSStrain.Visible = true;
CHK_Infected.Checked = true;
// If we're cured we have to have a strain infection.
if (CB_PKRSStrain.SelectedIndex == 0)
CB_PKRSStrain.SelectedIndex = 1;
}
else if (!CHK_Infected.Checked)
{
// Not Infected, Disable the other
Label_PKRS.Visible = CB_PKRSStrain.Visible = false;
CB_PKRSStrain.SelectedIndex = 0;
}
else
{
// Still Infected for a duration
Label_PKRSdays.Visible = CB_PKRSDays.Visible = true;
CB_PKRSDays.SelectedValue = 1;
}
// if not cured yet, days > 0
if (!CHK_Cured.Checked && CHK_Infected.Checked && CB_PKRSDays.SelectedIndex == 0)
CB_PKRSDays.SelectedIndex++;
setMarkings();
}
private void updatePKRSInfected(object sender, EventArgs e)
{
if (!fieldsInitialized) return;
2015-01-27 06:05:04 +00:00
if (CHK_Cured.Checked && !CHK_Infected.Checked) { CHK_Cured.Checked = false; return; }
if (CHK_Cured.Checked) return;
Label_PKRS.Visible = CB_PKRSStrain.Visible = CHK_Infected.Checked;
if (!CHK_Infected.Checked) { CB_PKRSStrain.SelectedIndex = 0; CB_PKRSDays.SelectedIndex = 0; Label_PKRSdays.Visible = CB_PKRSDays.Visible = false; }
else if (CB_PKRSStrain.SelectedIndex == 0) { CB_PKRSStrain.SelectedIndex = 1; Label_PKRSdays.Visible = CB_PKRSDays.Visible = true; updatePKRSCured(sender, e);}
// if not cured yet, days > 0
if (CHK_Infected.Checked && CB_PKRSDays.SelectedIndex == 0) CB_PKRSDays.SelectedIndex++;
}
private void updateCountry(object sender, EventArgs e)
{
if (Util.getIndex(sender as ComboBox) > 0)
setCountrySubRegion(CB_SubRegion, "sr_" + Util.getIndex(sender as ComboBox).ToString("000"));
}
2014-12-13 22:48:34 +00:00
private void updateSpecies(object sender, EventArgs e)
{
// Change Species Prompted
int Species = Util.getIndex(CB_Species);
int Level = Util.ToInt32(TB_Level.Text);
if (MT_Level.Visible) Level = Util.ToInt32(MT_Level.Text);
2014-12-13 22:48:34 +00:00
// Get Forms for Given Species
setForms();
2014-12-13 22:48:34 +00:00
// Recalculate EXP for Given Level
uint EXP = PKX.getEXP(Level, Species);
TB_EXP.Text = EXP.ToString();
2014-12-13 22:48:34 +00:00
// Check for Gender Changes
// Get Gender Threshold
2016-07-18 06:04:39 +00:00
int gt = SAV.Personal[Species].Gender;
int cg = Array.IndexOf(gendersymbols, Label_Gender.Text);
int Gender;
2014-12-13 22:48:34 +00:00
if (gt == 255) // Genderless
Gender = 2;
2014-12-13 22:48:34 +00:00
else if (gt == 254) // Female Only
Gender = 1;
else if (gt == 0) // Male Only
Gender = 0;
else if (cg == 2 || Util.getIndex(CB_GameOrigin) < 24)
Gender = (Util.getHEXval(TB_PID.Text) & 0xFF) <= gt ? 1 : 0;
else
Gender = cg;
Label_Gender.Text = gendersymbols[Gender];
Label_Gender.ForeColor = Gender == 2 ? Label_Species.ForeColor : (Gender == 1 ? Color.Red : Color.Blue);
setAbilityList();
2014-12-13 22:48:34 +00:00
updateForm(null, null);
// If species changes and no nickname, set the new name == speciesName.
if (!CHK_Nicknamed.Checked)
updateNickname(sender, e);
updateLegality();
2014-12-13 22:48:34 +00:00
}
private static List<ComboItem> getLocationList(GameVersion Version, int SaveFormat, bool egg)
2014-12-13 22:48:34 +00:00
{
if (SaveFormat == 2)
return metGen2;
if (egg)
{
if (Version < GameVersion.W && SaveFormat >= 5)
return metGen4;
2014-06-28 21:22:05 +00:00
}
switch (Version)
2014-06-28 21:22:05 +00:00
{
case GameVersion.CXD:
if (SaveFormat == 3)
return metGen3CXD;
break;
case GameVersion.R:
case GameVersion.S:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value <= 87).ToList(); // Ferry
break;
case GameVersion.E:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value <= 87 || (loc.Value >= 196 && loc.Value <= 212)).ToList(); // Trainer Hill
break;
case GameVersion.FR:
case GameVersion.LG:
if (SaveFormat == 3)
return metGen3.OrderByDescending(loc => loc.Value > 87 && loc.Value < 197).ToList(); // Celadon Dept.
break;
case GameVersion.D:
case GameVersion.P:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen4.Skip(4).OrderByDescending(loc => loc.Value <= 111)).ToList(); // Battle Park
break;
case GameVersion.Pt:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen4.Skip(4).OrderByDescending(loc => loc.Value <= 125)).ToList(); // Rock Peak Ruins
break;
case GameVersion.HG:
case GameVersion.SS:
if (SaveFormat == 4 || (SaveFormat >= 5 && egg))
return metGen4.Take(4).Concat(metGen4.Skip(4).OrderByDescending(loc => loc.Value > 125 && loc.Value < 234)).ToList(); // Celadon Dept.
break;
case GameVersion.B:
case GameVersion.W:
return metGen5;
case GameVersion.B2:
case GameVersion.W2:
return metGen5.Take(3).Concat(metGen5.Skip(3).OrderByDescending(loc => loc.Value <= 116)).ToList(); // Abyssal Ruins
case GameVersion.X:
case GameVersion.Y:
return metGen6.Take(3).Concat(metGen6.Skip(3).OrderByDescending(loc => loc.Value <= 168)).ToList(); // Unknown Dungeon
case GameVersion.OR:
case GameVersion.AS:
return metGen6.Take(3).Concat(metGen6.Skip(3).OrderByDescending(loc => loc.Value > 168 && loc.Value <= 354)).ToList(); // Secret Base
2014-12-13 22:48:34 +00:00
}
// Currently on a future game, return corresponding list for generation
if (Version <= GameVersion.CXD && SaveFormat == 4)
return metGen4.Where(loc => loc.Value == 0x37) // Pal Park to front
.Concat(metGen4.Take(4))
.Concat(metGen4.Skip(4).Where(loc => loc.Value != 0x37)).ToList();
if (Version < GameVersion.X && SaveFormat >= 5) // PokéTransfer to front
return metGen5.Where(loc => loc.Value == 30001)
.Concat(metGen5.Take(3))
.Concat(metGen5.Skip(3).Where(loc => loc.Value != 30001)).ToList();
return metGen6;
}
private void updateOriginGame(object sender, EventArgs e)
{
GameVersion Version = (GameVersion)Util.getIndex(CB_GameOrigin);
// check if differs
GameVersion newTrack = SaveUtil.getVersionGroup(Version);
if (newTrack != origintrack)
{
var met_list = getLocationList(Version, SAV.Generation, egg:false);
CB_MetLocation.DisplayMember = "Text";
CB_MetLocation.ValueMember = "Value";
CB_MetLocation.DataSource = new BindingSource(met_list, null);
CB_MetLocation.SelectedIndex = 0; // transporter or pal park for past gen pkm
2014-12-13 22:48:34 +00:00
var egg_list = getLocationList(Version, SAV.Generation, egg:true);
2014-12-13 22:48:34 +00:00
CB_EggLocation.DisplayMember = "Text";
CB_EggLocation.ValueMember = "Value";
CB_EggLocation.DataSource = new BindingSource(egg_list, null);
CB_EggLocation.SelectedIndex = CHK_AsEgg.Checked ? 1 : 0; // daycare : none
origintrack = newTrack;
// Stretch C/XD met location dropdowns
int width = CB_EggLocation.DropDownWidth;
if (Version == GameVersion.CXD && SAV.Generation == 3)
width = 2*width;
CB_MetLocation.DropDownWidth = width;
2014-06-28 21:22:05 +00:00
}
// Visibility logic for Gen 4 encounter type; only show for Gen 4 Pokemon.
if (SAV.Generation >= 4)
{
bool g4 = Version >= GameVersion.HG && Version <= GameVersion.Pt;
if ((int) Version == 9) // invalid
g4 = false;
CB_EncounterType.Visible = Label_EncounterType.Visible = g4;
if (!g4)
CB_EncounterType.SelectedValue = 0;
}
setMarkings(); // Set/Remove KB marking
if (!fieldsLoaded)
return;
pkm.Version = (int)Version;
updateLegality();
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateExtraByteValue(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (CB_ExtraBytes.Items.Count == 0)
return;
2014-12-13 22:48:34 +00:00
// Changed Extra Byte's Value
if (Util.ToInt32(((MaskedTextBox) sender).Text) > byte.MaxValue)
((MaskedTextBox) sender).Text = "255";
2014-12-13 22:48:34 +00:00
int value = Util.ToInt32(TB_ExtraByte.Text);
int offset = Convert.ToInt32(CB_ExtraBytes.Text, 16);
pkm.Data[offset] = (byte)value;
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateExtraByteIndex(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (CB_ExtraBytes.Items.Count == 0)
return;
2014-12-13 22:48:34 +00:00
// Byte changed, need to refresh the Text box for the byte's value.
TB_ExtraByte.Text = pkm.Data[Convert.ToInt32(CB_ExtraBytes.Text, 16)].ToString();
2014-06-28 21:22:05 +00:00
}
private void updateNatureModification(object sender, EventArgs e)
{
if (sender != CB_Nature) return;
int nature = Util.getIndex(CB_Nature);
int incr = nature / 5;
int decr = nature % 5;
Label[] labarray = { Label_ATK, Label_DEF, Label_SPE, Label_SPA, Label_SPD };
// Reset Label Colors
foreach (Label label in labarray)
label.ResetForeColor();
// Set Colored StatLabels only if Nature isn't Neutral
NatureTip.SetToolTip(CB_Nature,
incr != decr
? $"+{labarray[incr].Text} / -{labarray[decr].Text}".Replace(":", "")
: "-/-");
}
2014-12-13 22:48:34 +00:00
private void updateNickname(object sender, EventArgs e)
{
if (fieldsInitialized && ModifierKeys == Keys.Control && sender != null) // Import Showdown
{ clickShowdownImportPK6(sender, e); return; }
if (fieldsInitialized && ModifierKeys == Keys.Alt && sender != null) // Export Showdown
{ clickShowdownExportPK6(sender, e); return; }
if (!fieldsInitialized || CHK_Nicknamed.Checked)
return;
// Fetch Current Species and set it as Nickname Text
int species = Util.getIndex(CB_Species);
if (species < 1 || species > SAV.MaxSpeciesID)
TB_Nickname.Text = "";
else
{
// get language
int lang = Util.getIndex(CB_Language);
if (CHK_IsEgg.Checked) species = 0; // Set species to 0 to get the egg name.
string nick = PKX.getSpeciesName(CHK_IsEgg.Checked ? 0 : species, lang);
if (SAV.Generation < 5) // All caps GenIV and previous
nick = nick.ToUpper();
if (SAV.Generation < 3)
nick = nick.Replace(" ", "");
TB_Nickname.Text = nick;
2016-08-29 20:27:17 +00:00
if (SAV.Generation == 1)
((PK1)pkm).setNotNicknamed();
if (SAV.Generation == 2)
((PK2)pkm).setNotNicknamed();
}
}
2014-12-13 22:48:34 +00:00
private void updateNicknameClick(object sender, MouseEventArgs e)
{
2016-07-17 17:06:52 +00:00
TextBox tb = !(sender is TextBox) ? TB_Nickname : (TextBox) sender;
2014-12-13 22:48:34 +00:00
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(f2_Text)) as f2_Text;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
new f2_Text(tb).Show();
}
2014-12-13 22:48:34 +00:00
private void updateNotOT(object sender, EventArgs e)
{
2016-02-03 04:05:46 +00:00
if (string.IsNullOrWhiteSpace(TB_OTt2.Text))
{
2015-02-07 20:22:09 +00:00
clickGT(GB_OT, null); // Switch CT over to OT.
2014-12-13 22:48:34 +00:00
Label_CTGender.Text = "";
TB_Friendship.Text = pkm.CurrentFriendship.ToString();
}
2016-02-03 04:05:46 +00:00
else if (string.IsNullOrWhiteSpace(Label_CTGender.Text))
2014-12-13 22:48:34 +00:00
Label_CTGender.Text = gendersymbols[0];
}
2014-12-13 22:48:34 +00:00
private void updateIsEgg(object sender, EventArgs e)
{
if (CHK_IsEgg.Checked)
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
CHK_Nicknamed.Checked = false;
TB_Friendship.Text = "1";
if (SAV.Generation == 2)
pkm.IsEgg = true;
2014-12-12 05:44:05 +00:00
2014-12-13 22:48:34 +00:00
// If we are an egg, it won't have a met location.
CHK_AsEgg.Checked = true;
GB_EggConditions.Enabled = true;
CAL_MetDate.Value = new DateTime(2000, 01, 01);
CB_MetLocation.SelectedIndex = 2;
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
else // Not Egg
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
if (!CHK_Nicknamed.Checked)
updateNickname(null, null);
if (SAV.Generation == 2)
pkm.IsEgg = false;
TB_Friendship.Text = SAV.Personal[Util.getIndex(CB_Species)].BaseFriendship.ToString();
2014-12-13 22:48:34 +00:00
if (CB_EggLocation.SelectedIndex == 0)
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
CAL_EggDate.Value = new DateTime(2000, 01, 01);
CHK_AsEgg.Checked = false;
GB_EggConditions.Enabled = false;
2014-06-28 21:22:05 +00:00
}
}
2014-12-13 22:48:34 +00:00
// Display hatch counter if it is an egg, Display Friendship if it is not.
2016-08-29 05:21:55 +00:00
Label_HatchCounter.Visible = CHK_IsEgg.Checked && SAV.Generation > 1;
Label_Friendship.Visible = !CHK_IsEgg.Checked && SAV.Generation > 1;
2016-08-29 05:21:55 +00:00
// Update image to (not) show egg.
if (!fieldsInitialized) return;
updateNickname(null, null);
getQuickFiller(dragout);
2014-12-13 22:48:34 +00:00
}
private void updateMetAsEgg(object sender, EventArgs e)
{
GB_EggConditions.Enabled = CHK_AsEgg.Checked;
if (CHK_AsEgg.Checked)
{
if (!fieldsLoaded)
return;
CAL_EggDate.Value = DateTime.Now;
CB_EggLocation.SelectedIndex = 1;
return;
}
// Remove egg met data
CHK_IsEgg.Checked = false;
CAL_EggDate.Value = new DateTime(2000, 01, 01);
CB_EggLocation.SelectedValue = 0;
updateLegality();
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateShinyPID(object sender, EventArgs e)
2014-11-15 05:08:00 +00:00
{
2016-07-29 05:33:16 +00:00
pkm.TID = Util.ToInt32(TB_TID.Text);
pkm.SID = Util.ToInt32(TB_SID.Text);
pkm.PID = Util.getHEXval(TB_PID.Text);
pkm.Nature = Util.getIndex(CB_Nature);
pkm.Gender = PKX.getGender(Label_Gender.Text);
pkm.AltForm = CB_Form.SelectedIndex;
2016-08-09 01:42:42 +00:00
pkm.Version = Util.getIndex(CB_GameOrigin);
2014-11-15 05:08:00 +00:00
if (pkm.Format > 2)
pkm.setShinyPID();
else
{
TB_ATKIV.Text = "15";
TB_DEFIV.Text = "10";
TB_SPEIV.Text = "10";
TB_SPAIV.Text = "10";
updateIVs(null, null);
}
2016-07-29 05:33:16 +00:00
TB_PID.Text = pkm.PID.ToString("X8");
2014-11-15 05:08:00 +00:00
2016-08-09 01:42:42 +00:00
if (pkm.GenNumber < 6 && TB_EC.Visible)
2016-03-07 06:21:54 +00:00
TB_EC.Text = TB_PID.Text;
2014-12-13 22:48:34 +00:00
getQuickFiller(dragout);
2016-07-29 05:33:16 +00:00
updateLegality();
2014-11-15 05:08:00 +00:00
}
private void updateTSV(object sender, EventArgs e)
{
2016-06-21 04:11:48 +00:00
if (SAV.Generation < 6)
return;
var TSV = pkm.TSV;
Tip1.SetToolTip(TB_TID, "TSV: " + TSV.ToString("0000"));
Tip2.SetToolTip(TB_SID, "TSV: " + TSV.ToString("0000"));
pkm.PID = Util.getHEXval(TB_PID.Text);
var PSV = pkm.PSV;
Tip3.SetToolTip(TB_PID, "PSV: " + PSV.ToString("0000"));
}
2014-12-13 22:48:34 +00:00
private void update_ID(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
// Trim out nonhex characters
TB_PID.Text = Util.getHEXval(TB_PID.Text).ToString("X8");
TB_EC.Text = Util.getHEXval(TB_EC.Text).ToString("X8");
2014-12-13 22:48:34 +00:00
// Max TID/SID is 65535
if (Util.ToUInt32(TB_TID.Text) > ushort.MaxValue) TB_TID.Text = "65535";
if (Util.ToUInt32(TB_SID.Text) > ushort.MaxValue) TB_SID.Text = "65535";
setIsShiny(sender);
getQuickFiller(dragout);
2016-03-07 06:21:54 +00:00
updateIVs(null, null); // If the EC is changed, EC%6 (Characteristic) might be changed.
2014-12-13 22:48:34 +00:00
TB_PID.Select(60, 0); // position cursor at end of field
if (SAV.Generation <= 4 && fieldsLoaded)
{
fieldsLoaded = false;
pkm.PID = Util.getHEXval(TB_PID.Text);
CB_Nature.SelectedValue = pkm.Nature;
Label_Gender.Text = gendersymbols[pkm.Gender];
Label_Gender.ForeColor = pkm.Gender == 2 ? Label_Species.ForeColor : (pkm.Gender == 1 ? Color.Red : Color.Blue);
fieldsLoaded = true;
}
2014-12-13 22:48:34 +00:00
}
private void updateShadowID(object sender, EventArgs e)
{
if (!fieldsLoaded)
return;
FLP_Purification.Visible = NUD_ShadowID.Value > 0;
}
private void updatePurification(object sender, EventArgs e)
{
if (!fieldsLoaded)
return;
fieldsLoaded = false;
CHK_Shadow.Checked = NUD_Purification.Value == 0;
fieldsLoaded = true;
}
private void updateShadowCHK(object sender, EventArgs e)
{
if (!fieldsLoaded)
return;
fieldsLoaded = false;
NUD_Purification.Value = CHK_Shadow.Checked ? NUD_Purification.Maximum : 0;
fieldsLoaded = true;
}
private void validateComboBox(object sender)
2014-12-13 22:48:34 +00:00
{
if (!formInitialized)
return;
ComboBox cb = sender as ComboBox;
if (cb == null)
2016-02-01 07:15:54 +00:00
return;
2014-12-13 22:48:34 +00:00
cb.SelectionLength = 0;
if (cb.Text == "")
{ cb.SelectedIndex = 0; return; }
if (cb.SelectedValue == null)
cb.BackColor = Color.DarkSalmon;
else
cb.ResetBackColor();
}
private void validateComboBox(object sender, System.ComponentModel.CancelEventArgs e)
{
if (!(sender is ComboBox))
return;
validateComboBox(sender);
if (fieldsLoaded)
2016-02-01 07:15:54 +00:00
getQuickFiller(dragout);
2014-12-13 22:48:34 +00:00
}
private void validateComboBox2(object sender, EventArgs e)
{
if (!fieldsInitialized)
return;
validateComboBox(sender, null);
if (fieldsLoaded)
{
if (sender == CB_Ability && SAV.Generation >= 6)
TB_AbilityNumber.Text = (1 << CB_Ability.SelectedIndex).ToString();
if (sender == CB_Ability && SAV.Generation <= 5 && CB_Ability.SelectedIndex < 2) // not hidden
updateRandomPID(sender, e);
if (sender == CB_Nature && SAV.Generation <= 4)
updateRandomPID(sender, e);
}
updateNatureModification(sender, null);
2014-12-13 22:48:34 +00:00
updateIVs(null, null); // updating Nature will trigger stats to update as well
}
private void validateMove(object sender, EventArgs e)
{
if (!fieldsInitialized)
return;
validateComboBox(sender);
if (!fieldsLoaded)
return;
if (new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 }.Contains(sender)) // Move
updatePP(sender, e);
if (pkm.Format < 6)
return;
// Legality
pkm.Moves = new[] { Util.getIndex(CB_Move1), Util.getIndex(CB_Move2), Util.getIndex(CB_Move3), Util.getIndex(CB_Move4) };
pkm.RelearnMoves = new[] { Util.getIndex(CB_RelearnMove1), Util.getIndex(CB_RelearnMove2), Util.getIndex(CB_RelearnMove3), Util.getIndex(CB_RelearnMove4) };
updateLegality();
}
private void validateLocation(object sender, EventArgs e)
{
validateComboBox(sender);
if (!fieldsLoaded)
return;
pkm.Met_Location = Util.getIndex(CB_MetLocation);
pkm.Egg_Location = Util.getIndex(CB_EggLocation);
updateLegality();
}
2014-12-13 22:48:34 +00:00
private void removedropCB(object sender, KeyEventArgs e)
{
((ComboBox)sender).DroppedDown = false;
}
private void showLegality(PK6 pk, bool tabs, bool verbose)
{
LegalityAnalysis la = new LegalityAnalysis(pk);
if (tabs)
updateLegality(la);
Util.Alert(verbose ? la.VerboseReport : la.Report);
}
private void updateLegality(LegalityAnalysis la = null)
{
if (!fieldsLoaded)
return;
if (!(pkm is PK6))
return;
2016-07-17 17:06:52 +00:00
Legality = la ?? new LegalityAnalysis((PK6) pkm);
PB_Legal.Image = Legality.Valid ? Properties.Resources.valid : Properties.Resources.warn;
PB_Legal.Visible = pkm.Gen6 /*&& pkm is PK6*/ && !HaX;
// Refresh Move Legality
for (int i = 0; i < 4; i++)
movePB[i].Visible = !Legality.vMoves[i].Valid && !HaX;
int[] suggested = Legality.getSuggestedRelearn();
for (int i = 0; i < 4; i++)
{
if (pkm.RelearnMoves[i] == 0 && suggested[i] != 0)
relearnPB[i].Visible = !HaX;
else
relearnPB[i].Visible = !Legality.vRelearn[i].Valid && !HaX;
}
}
2014-12-13 22:48:34 +00:00
private void updateStats()
{
// Generate the stats.
ushort[] stats = pkm.getStats(SAV.Personal.getFormeEntry(pkm.Species, pkm.AltForm));
2014-06-28 21:22:05 +00:00
Stat_HP.Text = stats[0].ToString();
Stat_ATK.Text = stats[1].ToString();
Stat_DEF.Text = stats[2].ToString();
Stat_SPA.Text = stats[4].ToString();
Stat_SPD.Text = stats[5].ToString();
Stat_SPE.Text = stats[3].ToString();
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Recolor the Stat Labels based on boosted stats.
{
int incr = pkm.Nature / 5;
int decr = pkm.Nature % 5;
2014-06-28 21:22:05 +00:00
Label[] labarray = { Label_ATK, Label_DEF, Label_SPE, Label_SPA, Label_SPD };
2014-12-13 22:48:34 +00:00
// Reset Label Colors
foreach (Label label in labarray)
label.ResetForeColor();
2014-11-19 06:35:39 +00:00
2014-12-13 22:48:34 +00:00
// Set Colored StatLabels only if Nature isn't Neutral
if (incr == decr) return;
labarray[incr].ForeColor = Color.Red;
labarray[decr].ForeColor = Color.Blue;
2014-12-13 22:48:34 +00:00
}
2014-11-19 06:35:39 +00:00
}
private void updateUnicode()
{
if (!unicode)
{
gendersymbols = new[] { "M", "F", "-" };
BTN_Shinytize.Text = "*";
TB_Nickname.Font = TB_OT.Font = TB_OTt2.Font = Label_TID.Font;
}
else
{
gendersymbols = new[] { "♂", "♀", "-" };
BTN_Shinytize.Text = "☆";
TB_Nickname.Font = TB_OT.Font = TB_OTt2.Font = PKX.getPKXFont(11);
}
// Switch active gender labels to new if they are active.
if (PKX.getGender(Label_Gender.Text) < 2)
Label_Gender.Text = gendersymbols[PKX.getGender(Label_Gender.Text)];
if (PKX.getGender(Label_OTGender.Text) < 2)
Label_OTGender.Text = gendersymbols[PKX.getGender(Label_OTGender.Text)];
if (PKX.getGender(Label_CTGender.Text) < 2)
Label_CTGender.Text = gendersymbols[PKX.getGender(Label_CTGender.Text)];
}
2014-06-28 21:22:05 +00:00
// Secondary Windows for Ribbons/Amie/Memories
private void openRibbons(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
new RibbonEditor().ShowDialog();
}
private void openMedals(object sender, EventArgs e)
{
new SuperTrainingEditor().ShowDialog();
2014-06-28 21:22:05 +00:00
}
private void openHistory(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (pkm.Format < 6) return;
// Write back current values
PK6 pk6 = pkm as PK6;
pk6.Version = Util.getIndex(CB_GameOrigin);
pk6.HT_Name = TB_OTt2.Text;
pk6.OT_Name = TB_OT.Text;
pk6.IsEgg = CHK_IsEgg.Checked;
pk6.CurrentFriendship = Util.ToInt32(TB_Friendship.Text);
new MemoryAmie().ShowDialog();
TB_Friendship.Text = pk6.CurrentFriendship.ToString();
2014-06-28 21:22:05 +00:00
}
// Open/Save Array Manipulation //
public bool verifiedPKM()
2014-06-28 21:22:05 +00:00
{
if (ModifierKeys == (Keys.Control | Keys.Shift | Keys.Alt))
2014-11-15 05:08:00 +00:00
return true; // Override
2014-06-28 21:22:05 +00:00
// Make sure the PKX Fields are filled out properly (color check)
ComboBox[] cba = {
2014-12-13 22:48:34 +00:00
CB_Species, CB_Nature, CB_HeldItem, CB_Ability, // Main Tab
2014-06-28 21:22:05 +00:00
CB_MetLocation, CB_EggLocation, CB_Ball, // Met Tab
CB_Move1, CB_Move2, CB_Move3, CB_Move4, // Moves
CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 // Moves
2014-06-28 21:22:05 +00:00
};
ComboBox cb = cba.FirstOrDefault(c => c.BackColor == Color.DarkSalmon);
if (cb != null)
{
Control c = cb.Parent;
while (!(c is TabPage))
c = c.Parent;
tabMain.SelectedTab = c as TabPage;
2014-06-28 21:22:05 +00:00
}
else if (SAV.Generation >= 3 && Convert.ToUInt32(TB_EVTotal.Text) > 510 && !CHK_HackedStats.Checked)
tabMain.SelectedTab = Tab_Stats;
else if (Util.getIndex(CB_Species) == 0)
tabMain.SelectedTab = Tab_Main;
else
return true;
SystemSounds.Exclamation.Play();
return false;
2014-06-28 21:22:05 +00:00
}
public static string[] verifyPKMtoSAV(PKM pk)
{
// Check if PKM properties are outside of the valid range
List<string> errata = new List<string>();
if (SAV.Generation > 1)
{
ushort held;
2016-10-04 05:35:33 +00:00
switch (pk.GetType().Name)
{
case "PK2":
held = (ushort)(((PK2)pk).G2Item);
break;
case "CK3":
held = (ushort)(((CK3)pk).G3Item);
break;
case "XK3":
held = (ushort)(((XK3)pk).G3Item);
break;
case "PK3":
held = (ushort)(((PK3)pk).G3Item);
break;
default:
held = (ushort)(pk.HeldItem);
break;
}
if (held > itemlist.Length)
errata.Add($"Item Index beyond range: {held}");
else
{
if (held > SAV.MaxItemID)
errata.Add($"Game can't obtain item: {itemlist[held]}");
if (!pk.CanHoldItem(SAV.HeldItems))
errata.Add($"Game can't hold item: {itemlist[held]}");
}
}
if (pk.Species > specieslist.Length)
errata.Add($"Species Index beyond range: {pk.HeldItem}");
else if (SAV.MaxSpeciesID < pk.Species)
errata.Add($"Game can't obtain species: {specieslist[pk.Species]}");
if (pk.Moves.Any(m => m > movelist.Length))
errata.Add($"Item Index beyond range: {string.Join(", ", pk.Moves.Where(m => m > movelist.Length).Select(m => m.ToString()))}");
else if (pk.Moves.Any(m => m > SAV.MaxMoveID))
errata.Add($"Game can't have move: {string.Join(", ", pk.Moves.Where(m => m > SAV.MaxMoveID).Select(m => movelist[m]))}");
if (pk.Ability > abilitylist.Length)
errata.Add($"Ability Index beyond range: {pk.Ability}");
else if (pk.Ability > SAV.MaxAbilityID)
errata.Add($"Game can't have ability: {abilitylist[pk.Ability]}");
return errata.ToArray();
}
public PKM preparePKM(bool click = true)
2014-06-28 21:22:05 +00:00
{
if (click)
tabMain.Select(); // hack to make sure comboboxes are set (users scrolling through and immediately setting causes this)
PKM pk = getPKMfromFields();
return pk?.Clone();
}
2014-10-11 07:22:22 +00:00
// Drag & Drop Events
2014-06-28 21:22:05 +00:00
private void tabMain_DragEnter(object sender, DragEventArgs e)
{
if (e.AllowedEffect == (DragDropEffects.Copy | DragDropEffects.Link)) // external file
e.Effect = DragDropEffects.Copy;
else if (e.Data != null) // within
e.Effect = DragDropEffects.Move;
2014-06-28 21:22:05 +00:00
}
private void tabMain_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
2016-02-01 07:15:54 +00:00
openQuick(files[0]);
e.Effect = DragDropEffects.Copy;
Cursor = DefaultCursor;
2014-06-28 21:22:05 +00:00
}
// Decrypted Export
private void dragout_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && (ModifierKeys == Keys.Alt || ModifierKeys == Keys.Shift))
clickQR(sender, e);
if (e.Button == MouseButtons.Right)
return;
if (!verifiedPKM())
return;
2014-06-28 21:22:05 +00:00
// Create Temp File to Drag
PKM pkx = preparePKM();
bool encrypt = ModifierKeys == Keys.Control;
string filename = $"{Path.GetFileNameWithoutExtension(pkx.FileName)}{(encrypt ? ".ek" + pkx.Format : "."+pkx.Extension) }";
byte[] dragdata = encrypt ? pkx.EncryptedBoxData : pkx.DecryptedBoxData;
// Make file
string newfile = Path.Combine(Path.GetTempPath(), Util.CleanFileName(filename));
try
{
File.WriteAllBytes(newfile, dragdata);
PictureBox pb = (PictureBox)sender;
Cursor = DragInfo.Cursor = new Cursor(((Bitmap)pb.Image).GetHicon());
DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move);
2014-06-28 21:22:05 +00:00
}
catch (Exception x)
{ Util.Error("Drag & Drop Error", x); }
Cursor = DragInfo.Cursor = DefaultCursor;
File.Delete(newfile);
2014-06-28 21:22:05 +00:00
}
private void dragout_DragOver(object sender, DragEventArgs e)
2014-06-28 21:22:05 +00:00
{
e.Effect = DragDropEffects.Move;
}
// Dragout Display
2014-06-28 21:22:05 +00:00
private void dragoutHover(object sender, EventArgs e)
{
dragout.BackgroundImage = Util.getIndex(CB_Species) > 0 ? Properties.Resources.slotSet : Properties.Resources.slotDel;
2014-06-28 21:22:05 +00:00
}
private void dragoutLeave(object sender, EventArgs e)
{
dragout.BackgroundImage = Properties.Resources.slotTrans;
}
private void dragoutDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
openQuick(files[0]);
e.Effect = DragDropEffects.Copy;
Cursor = DefaultCursor;
2014-06-28 21:22:05 +00:00
}
#endregion
2014-06-28 21:22:05 +00:00
#region //// SAVE FILE FUNCTIONS ////
2014-12-14 19:06:17 +00:00
private void clickVerifyCHK(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (SAV.Edited) { Util.Alert("Save has been edited. Cannot integrity check."); return; }
2014-06-28 21:22:05 +00:00
2016-02-09 23:30:10 +00:00
if (SAV.ChecksumsValid) { Util.Alert("Checksums are valid."); return; }
if (DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Export Checksum Info to Clipboard?"))
Clipboard.SetText(SAV.ChecksumInfo);
2014-06-28 21:22:05 +00:00
}
private void clickExportSAVBAK(object sender, EventArgs e)
{
if (!SAV.Exportable)
return;
SaveFileDialog sfd = new SaveFileDialog
{ FileName = Util.CleanFileName(SAV.BAKName) };
if (sfd.ShowDialog() != DialogResult.OK)
return;
string path = sfd.FileName;
File.WriteAllBytes(path, SAV.BAK);
Util.Alert("Saved Backup of current SAV to:", path);
if (Directory.Exists(BackupPath)) return;
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo,
$"PKHeX can perform automatic backups if you create a folder with the name \"{BackupPath}\" in the same folder as PKHeX's executable.",
"Would you like to create the backup folder now and save backup of current save?")) return;
try { Directory.CreateDirectory(BackupPath); Util.Alert("Backup folder created!",
$"If you wish to no longer automatically back up save files, delete the \"{BackupPath}\" folder."); }
catch(Exception ex) { Util.Error($"Unable to create backup folder @ {BackupPath}", ex); }
}
private void clickExportSAV(object sender, EventArgs e)
{
if (!Menu_ExportSAV.Enabled)
return;
// Chunk Error Checking
string err = SAV.MiscSaveChecks();
if (err.Length > 0 && Util.Prompt(MessageBoxButtons.YesNo, err, "Continue saving?") != DialogResult.Yes)
return;
2016-02-01 07:15:54 +00:00
SaveFileDialog main = new SaveFileDialog
{
Filter = SAV.Filter,
2016-02-11 08:56:10 +00:00
FileName = SAV.FileName,
2016-02-01 07:15:54 +00:00
RestoreDirectory = true
};
2016-02-11 08:56:10 +00:00
if (Directory.Exists(SAV.FilePath))
main.InitialDirectory = SAV.FilePath;
// Export
2016-02-01 07:15:54 +00:00
if (main.ShowDialog() != DialogResult.OK) return;
2016-02-11 08:56:10 +00:00
if (SAV.HasBox)
2016-02-11 08:56:10 +00:00
SAV.CurrentBox = CB_BoxSelect.SelectedIndex;
bool dsv = Path.GetExtension(main.FileName)?.ToLower() == ".dsv";
File.WriteAllBytes(main.FileName, SAV.Write(dsv));
2016-02-11 08:56:10 +00:00
Util.Alert("SAV exported to:", main.FileName);
2014-06-28 21:22:05 +00:00
}
// Box/SAV Functions //
2014-12-14 19:06:17 +00:00
private void clickBoxRight(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
CB_BoxSelect.SelectedIndex = (CB_BoxSelect.SelectedIndex + 1) % SAV.BoxCount;
2014-06-28 21:22:05 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickBoxLeft(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
CB_BoxSelect.SelectedIndex = (CB_BoxSelect.SelectedIndex + SAV.BoxCount-1) % SAV.BoxCount;
2014-06-28 21:22:05 +00:00
}
private void clickBoxSort(object sender, EventArgs e)
{
if (tabBoxMulti.SelectedTab != Tab_Box)
return;
2016-07-15 03:37:18 +00:00
if (!SAV.HasBox)
return;
string modified;
if (ModifierKeys == (Keys.Alt | Keys.Shift) && DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Clear ALL Boxes?!"))
{
SAV.resetBoxes();
modified = "Boxes cleared!";
}
else if (ModifierKeys == Keys.Alt && DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Clear Current Box?"))
{
SAV.resetBoxes(CB_BoxSelect.SelectedIndex, CB_BoxSelect.SelectedIndex + 1);
modified = "Current Box cleared!";
}
else if (ModifierKeys == (Keys.Control | Keys.Shift) && DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Sort ALL Boxes?!"))
{
SAV.sortBoxes();
modified = "Boxes sorted!";
}
else if (ModifierKeys == Keys.Control && DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Sort Current Box?"))
{
SAV.sortBoxes(CB_BoxSelect.SelectedIndex, CB_BoxSelect.SelectedIndex + 1);
modified = "Current Box sorted!";
}
else
return;
setPKXBoxes();
updateBoxViewers();
Util.Alert(modified);
}
private void clickBoxDouble(object sender, MouseEventArgs e)
{
if (tabBoxMulti.SelectedTab == Tab_SAV)
{
clickSaveFileName(sender, e);
return;
}
if (tabBoxMulti.SelectedTab != Tab_Box)
return;
if (!SAV.HasBox)
return;
if (ModifierKeys != Keys.Shift)
{
var z = Application.OpenForms.Cast<Form>().FirstOrDefault(form => form.GetType() == typeof(SAV_BoxViewer)) as SAV_BoxViewer;
if (z != null)
{ Util.CenterToForm(z, this); z.BringToFront(); return; }
}
new SAV_BoxViewer(this).Show();
}
public int swapBoxesViewer(int viewBox)
{
int mainBox = CB_BoxSelect.SelectedIndex;
CB_BoxSelect.SelectedIndex = viewBox;
return mainBox;
}
public void notifyBoxViewerRefresh()
{
var views = Application.OpenForms.OfType<SAV_BoxViewer>();
foreach (var v in views.Where(v => DragInfo.WasDragParticipant(v, v.CurrentBox) == false))
v.setPKXBoxes();
if (DragInfo.WasDragParticipant(this, CB_BoxSelect.SelectedIndex) == false)
setPKXBoxes();
}
private void updateBoxViewers()
{
var views = Application.OpenForms.OfType<SAV_BoxViewer>();
foreach (var v in views.Where(v => v.CurrentBox == CB_BoxSelect.SelectedIndex))
v.setPKXBoxes();
}
private void clickSlot(object sender, EventArgs e)
{
switch (ModifierKeys)
{
case Keys.Control | Keys.Alt: clickClone(sender, e); break;
case Keys.Control: clickView(sender, e); break;
case Keys.Shift: clickSet(sender, e); break;
case Keys.Alt: clickDelete(sender, e); break;
}
}
2014-12-14 19:06:17 +00:00
private void clickView(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
int slot = getSlot(sender);
if (SlotPictureBoxes[slot].Image == null)
{ SystemSounds.Exclamation.Play(); return; }
int offset = getPKXOffset(slot);
if (offset < 0)
{
Util.Error($"Slot read error @ slot {slot}.");
return;
}
2014-06-28 21:22:05 +00:00
// Load the PKX file
PKM pk = 30 <= slot && slot < 36 ? SAV.getPartySlot(offset) : SAV.getStoredSlot(offset);
if (pk.Valid && pk.Species != 0)
2014-06-28 21:22:05 +00:00
{
try { populateFields(pk); }
catch { }
2014-06-28 21:22:05 +00:00
// Visual to display what slot is currently loaded.
getSlotColor(slot, Properties.Resources.slotView);
2014-06-28 21:22:05 +00:00
}
2014-07-31 22:06:48 +00:00
else
SystemSounds.Exclamation.Play();
2014-06-28 21:22:05 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickSet(object sender, EventArgs e)
2014-06-28 21:22:05 +00:00
{
if (!verifiedPKM()) return;
2014-06-28 21:22:05 +00:00
int slot = getSlot(sender);
if (slot == 30 && (CB_Species.SelectedIndex == 0 || CHK_IsEgg.Checked))
{ Util.Alert("Can't have empty/egg first slot."); return; }
2014-10-11 07:22:22 +00:00
int offset = getPKXOffset(slot);
if (offset < 0)
{
Util.Error($"Slot read error @ slot {slot}.");
return;
}
PKM pk = preparePKM();
string[] errata = verifyPKMtoSAV(pk);
if (errata.Length > 0 && DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, string.Join(Environment.NewLine, errata), "Continue?"))
return;
if (slot >= 30 && slot < 36) // Party
{
// If slot isn't overwriting existing PKM, make it write to the lowest empty PKM slot
if (SAV.PartyCount < slot + 1 - 30)
{ slot = SAV.PartyCount + 30; offset = getPKXOffset(slot); }
SAV.setPartySlot(pk, offset);
setParty();
getSlotColor(slot, Properties.Resources.slotSet);
}
else if (slot < 30 || HaX && slot >= 36 && slot < 42)
{
if (slot < 30)
{
UndoStack.Push(new SlotChange
{
Box = CB_BoxSelect.SelectedIndex,
Slot = slot,
Offset = offset,
OriginalData = SAV.getStoredSlot(offset)
});
Menu_Undo.Enabled = true;
}
SAV.setStoredSlot(pk, offset);
getQuickFiller(SlotPictureBoxes[slot], pk);
getSlotColor(slot, Properties.Resources.slotSet);
}
updateBoxViewers();
RedoStack.Clear(); Menu_Redo.Enabled = false;
2014-06-28 21:22:05 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickDelete(object sender, EventArgs e)
2014-10-11 07:22:22 +00:00
{
int slot = getSlot(sender);
if (slot == 30 && SAV.PartyCount == 1 && !HaX) { Util.Alert("Can't delete first slot."); return; }
int offset = getPKXOffset(slot);
if (offset < 0)
{
Util.Error($"Slot read error @ slot {slot}.");
return;
}
2014-10-11 07:22:22 +00:00
if (slot >= 30 && slot < 36) // Party
{
SAV.deletePartySlot(slot-30);
setParty();
getSlotColor(slot, Properties.Resources.slotDel);
return;
}
if (slot < 30 || HaX && slot >= 36 && slot < 42)
{
if (slot < 30)
{
UndoStack.Push(new SlotChange
{
Box = CB_BoxSelect.SelectedIndex,
Slot = slot,
Offset = offset,
OriginalData = SAV.getStoredSlot(offset)
});
Menu_Undo.Enabled = true;
}
SAV.setStoredSlot(SAV.BlankPKM, getPKXOffset(slot));
}
2014-10-11 07:22:22 +00:00
else return;
getQuickFiller(SlotPictureBoxes[slot], SAV.BlankPKM);
2014-10-11 07:22:22 +00:00
getSlotColor(slot, Properties.Resources.slotDel);
updateBoxViewers();
RedoStack.Clear(); Menu_Redo.Enabled = false;
2014-10-11 07:22:22 +00:00
}
private readonly Stack<SlotChange> UndoStack = new Stack<SlotChange>();
private readonly Stack<SlotChange> RedoStack = new Stack<SlotChange>();
private void clickUndo(object sender, EventArgs e)
{
if (!UndoStack.Any())
return;
SlotChange change = UndoStack.Pop();
if (change.Slot >= 30)
return;
RedoStack.Push(new SlotChange
{
Slot = change.Slot,
Box = change.Box,
Offset = change.Offset,
OriginalData = SAV.getStoredSlot(change.Offset)
});
undoSlotChange(change);
}
private void clickRedo(object sender, EventArgs e)
{
if (!RedoStack.Any())
return;
SlotChange change = RedoStack.Pop();
if (change.Slot >= 30)
return;
UndoStack.Push(new SlotChange
{
Slot = change.Slot,
Box = change.Box,
Offset = change.Offset,
OriginalData = SAV.getStoredSlot(change.Offset)
});
undoSlotChange(change);
}
private void undoSlotChange(SlotChange change)
{
int slot = change.Slot;
int offset = change.Offset;
PKM pk = (PKM)change.OriginalData;
if (CB_BoxSelect.SelectedIndex != change.Box)
CB_BoxSelect.SelectedIndex = change.Box;
SAV.setStoredSlot(pk, offset);
getQuickFiller(SlotPictureBoxes[slot], pk);
getSlotColor(slot, Properties.Resources.slotSet);
Menu_Undo.Enabled = UndoStack.Any();
Menu_Redo.Enabled = RedoStack.Any();
SystemSounds.Asterisk.Play();
}
2014-12-14 19:06:17 +00:00
private void clickClone(object sender, EventArgs e)
{
if (getSlot(sender) > 30) return; // only perform action if cloning to boxes
if (!verifiedPKM()) return; // don't copy garbage to the box
PKM pk;
if (Util.Prompt(MessageBoxButtons.YesNo, $"Clone Pokemon from Editing Tabs to all slots in {CB_BoxSelect.Text}?") == DialogResult.Yes)
pk = preparePKM();
else if (Util.Prompt(MessageBoxButtons.YesNo, $"Delete all Pokemon in {CB_BoxSelect.Text}?") == DialogResult.Yes)
pk = SAV.BlankPKM;
else
return;
for (int i = 0; i < 30; i++) // set to every slot in box
{
SAV.setStoredSlot(pk, getPKXOffset(i));
getQuickFiller(SlotPictureBoxes[i], pk);
}
updateBoxViewers();
}
private void clickLegality(object sender, EventArgs e)
{
int slot = getSlot(sender);
PKM pk;
if (slot >= 0)
pk = SAV.getStoredSlot(getPKXOffset(slot));
else if (verifiedPKM())
pk = preparePKM();
else
return;
if (pk.Species == 0 || !pk.ChecksumValid)
{ SystemSounds.Asterisk.Play(); return; }
if (typeof (PK6) != pk.GetType())
{
Util.Alert($"Checking legality of {pk.GetType().Name} files is not supported.");
return;
}
showLegality(pk as PK6, slot < 0, ModifierKeys == Keys.Control);
}
private void updateSaveSlot(object sender, EventArgs e)
{
if (SAV.Version != GameVersion.BATREV)
return;
((SAV4BR)SAV).CurrentSlot = Util.getIndex(CB_SaveSlot);
setPKXBoxes();
}
private void updateEggRNGSeed(object sender, EventArgs e)
{
if (TB_RNGSeed.Text.Length == 0)
{
// Reset to 0
TB_RNGSeed.Text = 0.ToString("X"+SAV.DaycareSeedSize);
return; // recursively triggers this method, no need to continue
}
string filterText = Util.getOnlyHex(TB_RNGSeed.Text);
if (filterText.Length != TB_RNGSeed.Text.Length)
{
Util.Alert("Expected HEX (0-9, A-F).", "Received: " + Environment.NewLine + TB_RNGSeed.Text);
// Reset to Stored Value
var seed = SAV.getDaycareRNGSeed(SAV.DaycareIndex);
if (seed != null)
TB_RNGSeed.Text = ((ulong)seed).ToString("X"+SAV.DaycareSeedSize);
return; // recursively triggers this method, no need to continue
}
// Write final value back to the save
ulong value = Convert.ToUInt64(filterText, 16);
if (value != SAV.getDaycareRNGSeed(SAV.DaycareIndex))
{
SAV.setDaycareRNGSeed(SAV.DaycareIndex, value);
SAV.Edited = true;
}
}
private void updateU64(object sender, EventArgs e)
2015-12-17 03:33:58 +00:00
{
TextBox tb = sender as TextBox;
if (tb.Text.Length == 0)
2015-12-17 03:33:58 +00:00
{
// Reset to 0
tb.Text = 0.ToString("X16");
2015-12-17 03:33:58 +00:00
return; // recursively triggers this method, no need to continue
}
// Currently saved Value
ulong oldval = 0;
if (SAV.Generation == 6)
{
SAV6 sav6 = (SAV6) SAV;
if (tb == TB_GameSync)
oldval = sav6.GameSyncID;
else if (tb == TB_Secure1)
oldval = sav6.Secure1;
else if (tb == TB_Secure2)
oldval = sav6.Secure2;
}
string filterText = Util.getOnlyHex(tb.Text);
if (filterText.Length != tb.Text.Length)
{
Util.Alert("Expected HEX (0-9, A-F).", "Received: " + Environment.NewLine + tb.Text);
// Reset to Stored Value
tb.Text = oldval.ToString("X16");
return; // recursively triggers this method, no need to continue
}
// Write final value back to the save
ulong newval = Convert.ToUInt64(filterText, 16);
if (newval == oldval) return;
if (SAV.Generation == 6)
{
SAV6 sav6 = (SAV6) SAV;
if (tb == TB_GameSync)
sav6.GameSyncID = newval;
else if (tb == TB_Secure1)
sav6.Secure1 = newval;
else if (tb == TB_Secure2)
sav6.Secure2 = newval;
SAV.Edited = true;
}
}
2016-08-29 20:27:17 +00:00
private void updateIsNicknamed(object sender, EventArgs e)
{
if (!fieldsLoaded)
return;
2016-08-29 20:27:17 +00:00
if (!CHK_Nicknamed.Checked)
{
int species = Util.getIndex(CB_Species);
if (species < 1 || species > SAV.MaxSpeciesID)
return;
int lang = Util.getIndex(CB_Language);
if (CHK_IsEgg.Checked) species = 0; // Set species to 0 to get the egg name.
string nick = PKX.getSpeciesName(CHK_IsEgg.Checked ? 0 : species, lang);
if (SAV.Generation < 5) // All caps GenIV and previous
nick = nick.ToUpper();
if (SAV.Generation < 3)
nick = nick.Replace(" ", "");
2016-08-29 20:27:17 +00:00
if (TB_Nickname.Text != nick)
{
CHK_Nicknamed.Checked = true;
pkm.Nickname = TB_Nickname.Text;
}
}
}
// Generic Subfunctions //
private void setParty()
{
PKM[] party = SAV.PartyData;
PKM[] battle = SAV.BattleBoxData;
// Refresh slots
if (SAV.HasParty)
{
for (int i = 0; i < party.Length; i++)
getQuickFiller(SlotPictureBoxes[i + 30], party[i]);
for (int i = party.Length; i < 6; i++)
SlotPictureBoxes[i + 30].Image = null;
}
if (SAV.HasBattleBox)
{
for (int i = 0; i < battle.Length; i++)
getQuickFiller(SlotPictureBoxes[i + 36], battle[i]);
for (int i = battle.Length; i < 6; i++)
SlotPictureBoxes[i + 36].Image = null;
}
2014-06-28 21:22:05 +00:00
}
private int getPKXOffset(int slot)
{
if (slot < 30) // Box Slot
return SAV.getBoxOffset(CB_BoxSelect.SelectedIndex) + slot * SAV.SIZE_STORED;
slot -= 30;
if (slot < 6) // Party Slot
return SAV.getPartyOffset(slot);
slot -= 6;
if (slot < 6) // Battle Box Slot
return SAV.BattleBox + slot * SAV.SIZE_STORED;
slot -= 6;
if (slot < 2) // Daycare
return SAV.getDaycareSlotOffset(SAV.DaycareIndex, slot);
slot -= 2;
if (slot == 0) // GTS
return SAV.GTS;
slot -= 1;
if (slot == 0) // Fused
return SAV.Fused;
slot -= 1;
if (slot < 3) // SUBE
return SAV.SUBE + slot * (SAV.SIZE_STORED + 4);
return -1;
2014-06-28 21:22:05 +00:00
}
private int getSlot(object sender)
{
2016-02-01 07:15:54 +00:00
sender = ((sender as ToolStripItem)?.Owner as ContextMenuStrip)?.SourceControl ?? sender as PictureBox;
return Array.IndexOf(SlotPictureBoxes, sender);
2014-06-28 21:22:05 +00:00
}
public void setPKXBoxes()
2014-06-28 21:22:05 +00:00
{
if (SAV.HasBox)
{
int boxoffset = SAV.getBoxOffset(CB_BoxSelect.SelectedIndex);
int boxbgval = SAV.getBoxWallpaper(CB_BoxSelect.SelectedIndex);
PAN_Box.BackgroundImage = BoxWallpaper.getWallpaper(SAV, boxbgval);
for (int i = 0; i < 30; i++)
{
if (i < SAV.BoxSlotCount)
2016-08-29 05:21:55 +00:00
{
getSlotFiller(boxoffset + SAV.SIZE_STORED * i, SlotPictureBoxes[i]);
}
else
{
SlotPictureBoxes[i].Image = null;
2016-08-29 05:21:55 +00:00
SlotPictureBoxes[i].Visible = false;
}
}
}
2014-06-28 21:22:05 +00:00
// Reload Party
if (SAV.HasParty)
{
for (int i = 0; i < 6; i++)
getSlotFiller(SAV.getPartyOffset(i), SlotPictureBoxes[i + 30]);
}
2014-06-28 21:22:05 +00:00
// Reload Battle Box
if (SAV.HasBattleBox)
{
for (int i = 0; i < 6; i++)
getSlotFiller(SAV.BattleBox + SAV.SIZE_STORED * i, SlotPictureBoxes[i + 36]);
}
2014-06-28 21:22:05 +00:00
// Reload Daycare
if (SAV.HasDaycare)
2014-06-28 21:22:05 +00:00
{
Label[] L_SlotOccupied = { L_DC1, L_DC2 };
TextBox[] TB_SlotEXP = { TB_Daycare1XP, TB_Daycare2XP };
Label[] L_SlotEXP = { L_XP1, L_XP2 };
for (int i = 0; i < 2; i++)
2014-06-28 21:22:05 +00:00
{
getSlotFiller(SAV.getDaycareSlotOffset(SAV.DaycareIndex, i), SlotPictureBoxes[i + 42]);
uint? exp = SAV.getDaycareEXP(SAV.DaycareIndex, i);
TB_SlotEXP[i].Visible = L_SlotEXP[i].Visible = exp != null;
TB_SlotEXP[i].Text = exp.ToString();
bool? occ = SAV.getDaycareOccupied(SAV.DaycareIndex, i);
L_SlotOccupied[i].Visible = occ != null;
if (occ == true) // If Occupied
L_SlotOccupied[i].Text = $"{i + 1}: ✓";
else
{
L_SlotOccupied[i].Text = $"{i + 1}: ✘";
SlotPictureBoxes[i + 42].Image = Util.ChangeOpacity(SlotPictureBoxes[i + 42].Image, 0.6);
}
2014-06-28 21:22:05 +00:00
}
bool? egg = SAV.getDaycareHasEgg(SAV.DaycareIndex);
DayCare_HasEgg.Visible = egg != null;
DayCare_HasEgg.Checked = egg == true;
ulong? seed = SAV.getDaycareRNGSeed(SAV.DaycareIndex);
L_DaycareSeed.Visible = TB_RNGSeed.Visible = seed != null;
if (seed != null)
{
TB_RNGSeed.MaxLength = SAV.DaycareSeedSize;
TB_RNGSeed.Text = ((ulong)seed).ToString("X"+SAV.DaycareSeedSize);
}
2014-06-28 21:22:05 +00:00
}
// GTS
if (SAV.HasGTS)
getSlotFiller(SAV.GTS, SlotPictureBoxes[44]);
2014-06-28 21:22:05 +00:00
// Fused
if (SAV.HasFused)
getSlotFiller(SAV.Fused, SlotPictureBoxes[45]);
2014-06-28 21:22:05 +00:00
// SUBE
if (SAV.HasSUBE)
2014-06-28 21:22:05 +00:00
for (int i = 0; i < 3; i++)
{
int offset = SAV.SUBE + i * (SAV.SIZE_STORED + 4);
if (BitConverter.ToUInt64(SAV.Data, offset) != 0)
getSlotFiller(offset, SlotPictureBoxes[46 + i]);
else SlotPictureBoxes[46 + i].Image = null;
2014-06-28 21:22:05 +00:00
}
// Recoloring of a storage box slot (to not show for other storage boxes)
if (colorizedslot <= SAV.BoxCount)
SlotPictureBoxes[colorizedslot].BackgroundImage = colorizedbox == CB_BoxSelect.SelectedIndex ? colorizedcolor : null;
2014-06-28 21:22:05 +00:00
}
private void setBoxNames()
2014-06-28 21:22:05 +00:00
{
if (!SAV.HasBox)
return;
2014-06-28 21:22:05 +00:00
// Build ComboBox Dropdown Items
try
{
CB_BoxSelect.Items.Clear();
for (int i = 0; i < SAV.BoxCount; i++)
CB_BoxSelect.Items.Add(SAV.getBoxName(i));
2014-06-28 21:22:05 +00:00
}
catch
{
CB_BoxSelect.Items.Clear();
for (int i = 1; i <= SAV.BoxCount; i++)
CB_BoxSelect.Items.Add($"BOX {i}");
2014-06-28 21:22:05 +00:00
}
if (SAV.CurrentBox < CB_BoxSelect.Items.Count)
CB_BoxSelect.SelectedIndex = SAV.CurrentBox; // restore selected box
2014-06-28 21:22:05 +00:00
}
private void getQuickFiller(PictureBox pb, PKM pk = null)
{
if (!fieldsInitialized) return;
pk = pk ?? preparePKM(false); // don't perform control loss click
if (pb == dragout) mnuLQR.Enabled = pk.Species != 0; // Species
pb.Image = pk.Species != 0 ? pk.Sprite : null;
if (pb.BackColor == Color.Red)
pb.BackColor = Color.Transparent;
}
2014-06-28 21:22:05 +00:00
private void getSlotFiller(int offset, PictureBox pb)
{
if (SAV.getData(offset, SAV.SIZE_STORED).SequenceEqual(new byte[SAV.SIZE_STORED]))
{
// 00s present in slot.
pb.Image = null;
pb.BackColor = Color.Transparent;
2016-08-29 05:21:55 +00:00
pb.Visible = true;
return;
}
PKM p = SAV.getStoredSlot(offset);
if (!p.Valid) // Invalid
{
// Bad Egg present in slot.
pb.Image = null;
pb.BackColor = Color.Red;
2016-08-29 05:21:55 +00:00
pb.Visible = true;
return;
}
// Something stored in slot. Only display if species is valid.
pb.Image = p.Species == 0 ? null : p.Sprite;
pb.BackColor = Color.Transparent;
2016-08-29 05:21:55 +00:00
pb.Visible = true;
2014-06-28 21:22:05 +00:00
}
private void getSlotColor(int slot, Image color)
2014-06-28 21:22:05 +00:00
{
foreach (PictureBox t in SlotPictureBoxes)
t.BackgroundImage = null;
2014-08-17 01:42:51 +00:00
if (slot < 30)
colorizedbox = CB_BoxSelect.SelectedIndex;
2014-08-17 01:42:51 +00:00
SlotPictureBoxes[slot].BackgroundImage = color;
2014-06-28 21:22:05 +00:00
colorizedcolor = color;
colorizedslot = slot;
}
private void getBox(object sender, EventArgs e)
{
if (SAV.CurrentBox != CB_BoxSelect.SelectedIndex)
{
SAV.CurrentBox = CB_BoxSelect.SelectedIndex;
SAV.Edited = true; // Dumb
}
2014-10-10 02:59:57 +00:00
setPKXBoxes();
2014-06-28 21:22:05 +00:00
}
private void switchDaycare(object sender, EventArgs e)
{
if (!SAV.ORAS) return;
if (DialogResult.Yes == Util.Prompt(MessageBoxButtons.YesNo, "Would you like to switch the view to the other Daycare?",
$"Currently viewing daycare {SAV.DaycareIndex + 1}."))
// If ORAS, alter the daycare offset via toggle.
SAV.DaycareIndex ^= 1;
// Refresh Boxes
setPKXBoxes();
}
private void dumpBoxesToDB(string path, bool individualBoxFolders)
{
PKM[] boxdata = SAV.BoxData;
if (boxdata == null) { Util.Error("Null argument when dumping boxes."); return; }
2015-11-20 06:44:16 +00:00
for (int i = 0; i < boxdata.Length; i++)
{
PKM pk = boxdata[i];
if (pk.Species == 0 || !pk.Valid)
2015-11-14 02:29:59 +00:00
continue;
string fileName = Util.CleanFileName(pk.FileName);
string boxfolder = "";
if (individualBoxFolders)
{
2016-09-14 16:00:58 +00:00
boxfolder = SAV.getBoxName(i/SAV.BoxSlotCount);
Directory.CreateDirectory(Path.Combine(path, boxfolder));
2014-06-28 21:22:05 +00:00
}
if (!File.Exists(Path.Combine(Path.Combine(path, boxfolder), fileName)))
2016-09-07 02:35:36 +00:00
File.WriteAllBytes(Path.Combine(Path.Combine(path, boxfolder), fileName), pk.DecryptedBoxData);
2014-06-28 21:22:05 +00:00
}
}
private void loadBoxesFromDB(string path)
{
2016-02-03 04:05:46 +00:00
if (string.IsNullOrWhiteSpace(path)) return;
if (!SAV.HasBox) return;
DialogResult dr = Util.Prompt(MessageBoxButtons.YesNoCancel, "Clear subsequent boxes when importing data?", "If you only want to overwrite for new data, press no.");
if (dr == DialogResult.Cancel)
return;
if (dr == DialogResult.Yes)
SAV.resetBoxes(CB_BoxSelect.SelectedIndex);
bool? noSetb = getPKMSetOverride();
2016-09-14 16:00:58 +00:00
int ctr = CB_BoxSelect.SelectedIndex*SAV.BoxSlotCount;
int pastctr = 0;
string[] filepaths = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
2014-08-17 01:42:51 +00:00
foreach (byte[] data in from file in filepaths where PKX.getIsPKM(new FileInfo(file).Length) select File.ReadAllBytes(file))
2014-06-28 21:22:05 +00:00
{
string c;
PKM temp = PKMConverter.getPKMfromBytes(data);
PKM pk = PKMConverter.convertToFormat(temp, SAV.PKMType, out c);
if (pk != null) // Write to save
{
if (verifyPKMtoSAV(pk).Length > 0)
continue;
2016-09-14 16:00:58 +00:00
SAV.setStoredSlot(pk, SAV.getBoxOffset(ctr/SAV.BoxSlotCount) + ctr%SAV.BoxSlotCount * SAV.SIZE_STORED, noSetb);
if (pk.Format != temp.Format) // Transferred
pastctr++;
2016-09-14 16:00:58 +00:00
if (++ctr == SAV.BoxCount*SAV.BoxSlotCount) // Boxes full!
break;
2014-06-28 21:22:05 +00:00
}
Console.WriteLine(c);
2014-06-28 21:22:05 +00:00
}
2016-09-14 16:00:58 +00:00
ctr -= SAV.BoxSlotCount * CB_BoxSelect.SelectedIndex; // actual imported count
if (ctr <= 0)
return;
setPKXBoxes();
updateBoxViewers();
string result = $"Loaded {ctr} files to boxes.";
if (pastctr > 0)
Util.Alert(result, $"Conversion successful for {pastctr} past generation files.");
else
Util.Alert(result);
2014-06-28 21:22:05 +00:00
}
2015-01-25 19:24:00 +00:00
private void B_SaveBoxBin_Click(object sender, EventArgs e)
2015-01-24 19:16:20 +00:00
{
if (!SAV.HasBox)
{ Util.Alert("Save file does not have boxes to dump!"); return; }
DialogResult dr = Util.Prompt(MessageBoxButtons.YesNoCancel,
"Yes: Export All Boxes" + Environment.NewLine +
$"No: Export {CB_BoxSelect.Text} (Box {CB_BoxSelect.SelectedIndex + 1})" + Environment.NewLine +
"Cancel: Abort");
2015-01-25 19:24:00 +00:00
if (dr == DialogResult.Yes)
{
SaveFileDialog sfd = new SaveFileDialog {Filter = "Box Data|*.bin", FileName = "pcdata.bin"};
if (sfd.ShowDialog() != DialogResult.OK)
return;
File.WriteAllBytes(sfd.FileName, SAV.getPCBin());
2015-01-25 19:24:00 +00:00
}
else if (dr == DialogResult.No)
2015-01-24 19:16:20 +00:00
{
SaveFileDialog sfd = new SaveFileDialog {Filter = "Box Data|*.bin", FileName = $"boxdata {CB_BoxSelect.Text}.bin"};
if (sfd.ShowDialog() != DialogResult.OK)
return;
File.WriteAllBytes(sfd.FileName, SAV.getBoxBin(CB_BoxSelect.SelectedIndex));
2015-01-24 19:16:20 +00:00
}
}
private bool? getPKMSetOverride()
{
var yn = Menu_ModifyPKM.Checked ? "Yes" : "No";
DialogResult noSet = Util.Prompt(MessageBoxButtons.YesNoCancel,
"Loading overrides:",
"Yes - Modify .pk* when set to SAV" + Environment.NewLine +
"No - Don't modify .pk*" + Environment.NewLine +
$"Cancel - Use current settings ({yn})");
return noSet == DialogResult.Yes ? true : (noSet == DialogResult.No ? (bool?)false : null);
}
2014-12-14 19:06:17 +00:00
// Subfunction Save Buttons //
2014-06-28 21:22:05 +00:00
private void B_OpenWondercards_Click(object sender, EventArgs e)
{
new SAV_Wondercard(sender as MysteryGift).ShowDialog();
2014-06-28 21:22:05 +00:00
}
private void B_OpenBoxLayout_Click(object sender, EventArgs e)
{
new SAV_BoxLayout(CB_BoxSelect.SelectedIndex).ShowDialog();
setBoxNames(); // fix box names
setPKXBoxes(); // refresh box background
updateBoxViewers(); // update subviewers
2014-06-28 21:22:05 +00:00
}
private void B_OpenTrainerInfo_Click(object sender, EventArgs e)
{
if (SAV.Generation < 6)
new SAV_SimpleTrainer().ShowDialog();
else if (SAV.Generation == 6)
new SAV_Trainer().ShowDialog();
// Refresh conversion info
PKMConverter.updateConfig(SAV.SubRegion, SAV.Country, SAV.ConsoleRegion, SAV.OT, SAV.Gender);
2014-06-28 21:22:05 +00:00
}
private void B_OpenPokepuffs_Click(object sender, EventArgs e)
{
new SAV_Pokepuff().ShowDialog();
2014-06-28 21:22:05 +00:00
}
private void B_OpenItemPouch_Click(object sender, EventArgs e)
{
new SAV_Inventory().ShowDialog();
2014-06-28 21:22:05 +00:00
}
private void B_OpenBerryField_Click(object sender, EventArgs e)
{
new SAV_BerryFieldXY().ShowDialog();
}
private void B_OpenPokeblocks_Click(object sender, EventArgs e)
{
new SAV_PokeBlockORAS().ShowDialog();
2014-06-28 21:22:05 +00:00
}
private void B_OpenEventFlags_Click(object sender, EventArgs e)
{
new SAV_EventFlags().ShowDialog();
2014-06-28 21:22:05 +00:00
}
2014-07-31 22:06:48 +00:00
private void B_OpenSuperTraining_Click(object sender, EventArgs e)
{
new SAV_SuperTrain().ShowDialog();
2014-07-31 22:06:48 +00:00
}
private void B_OpenOPowers_Click(object sender, EventArgs e)
{
if (SAV.Generation != 6)
return;
if (SAV.ORAS)
2014-11-25 03:53:10 +00:00
{
2014-12-11 06:50:40 +00:00
DialogResult dr = Util.Prompt(MessageBoxButtons.YesNo, "No editing support for ORAS :(", "Max O-Powers with a working code?");
if (dr != DialogResult.Yes) return;
2016-02-03 04:05:46 +00:00
new byte[]
{
2016-02-03 04:05:46 +00:00
0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x00, 0x00, 0x00,
}.CopyTo(SAV.Data, ((SAV6) SAV).OPower);
2014-11-25 03:53:10 +00:00
}
else if (SAV.XY)
new SAV_OPower().ShowDialog();
}
2014-07-28 01:30:54 +00:00
private void B_OpenPokedex_Click(object sender, EventArgs e)
{
if (SAV.ORAS)
new SAV_PokedexORAS().ShowDialog();
else if (SAV.XY)
new SAV_PokedexXY().ShowDialog();
else if (SAV.RBY || SAV.GSC)
2016-08-30 00:48:05 +00:00
new SAV_SimplePokedex().ShowDialog();
2014-07-28 01:30:54 +00:00
}
2014-06-28 21:22:05 +00:00
private void B_OUTPasserby_Click(object sender, EventArgs e)
{
if (SAV.Generation != 6)
return;
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Export Passerby Info to Clipboard?"))
return;
string result = "PSS List" + Environment.NewLine;
string[] headers = { "PSS Data - Friends", "PSS Data - Acquaintances", "PSS Data - Passerby", };
int offset = ((SAV6) SAV).PSS;
2014-06-28 21:22:05 +00:00
for (int g = 0; g < 3; g++)
{
result += Environment.NewLine
+ "----" + Environment.NewLine
+ headers[g] + Environment.NewLine
+ "----" + Environment.NewLine;
// uint count = BitConverter.ToUInt32(savefile, offset + 0x4E20);
2014-06-28 21:22:05 +00:00
int r_offset = offset;
for (int i = 0; i < 100; i++)
{
ulong unkn = BitConverter.ToUInt64(SAV.Data, r_offset);
if (unkn == 0) break; // No data present here
if (i > 0) result += Environment.NewLine + Environment.NewLine;
2014-06-28 21:22:05 +00:00
string otname = Util.TrimFromZero(Encoding.Unicode.GetString(SAV.Data, r_offset + 8, 0x1A));
string message = Util.TrimFromZero(Encoding.Unicode.GetString(SAV.Data, r_offset + 0x22, 0x22));
2014-06-28 21:22:05 +00:00
// Trim terminated
// uint unk1 = BitConverter.ToUInt32(savefile, r_offset + 0x44);
// ulong unk2 = BitConverter.ToUInt64(savefile, r_offset + 0x48);
// uint unk3 = BitConverter.ToUInt32(savefile, r_offset + 0x50);
// uint unk4 = BitConverter.ToUInt16(savefile, r_offset + 0x54);
byte region = SAV.Data[r_offset + 0x56];
byte country = SAV.Data[r_offset + 0x57];
byte game = SAV.Data[r_offset + 0x5A];
// ulong outfit = BitConverter.ToUInt64(savefile, r_offset + 0x5C);
int favpkm = BitConverter.ToUInt16(SAV.Data, r_offset + 0x9C) & 0x7FF;
string gamename;
try { gamename = gamelist[game]; }
catch { gamename = "UNKNOWN GAME"; }
2014-12-17 03:12:16 +00:00
string[] cr = PKX.getCountryRegionText(country, region, curlanguage);
result +=
2014-12-11 07:00:25 +00:00
"OT: " + otname + Environment.NewLine +
"Message: " + message + Environment.NewLine +
"Game: " + gamename + Environment.NewLine +
"Country: " + cr[0] + Environment.NewLine +
"Region: " + cr[1] + Environment.NewLine +
"Favorite: " + specieslist[favpkm];
2014-12-11 07:00:25 +00:00
r_offset += 0xC8; // Advance to next entry
2014-06-28 21:22:05 +00:00
}
offset += 0x5000; // Advance to next block
2014-06-28 21:22:05 +00:00
}
Clipboard.SetText(result);
2014-06-28 21:22:05 +00:00
}
private void B_OUTHallofFame_Click(object sender, EventArgs e)
{
new SAV_HallOfFame().ShowDialog();
2014-06-28 21:22:05 +00:00
}
2014-11-23 22:23:40 +00:00
private void B_OpenSecretBase_Click(object sender, EventArgs e)
{
new SAV_SecretBase().ShowDialog();
2014-11-23 22:23:40 +00:00
}
private void B_LinkInfo_Click(object sender, EventArgs e)
{
new SAV_Link6().ShowDialog();
}
private void B_CGearSkin_Click(object sender, EventArgs e)
{
new SAV_CGearSkin().ShowDialog();
}
2014-12-14 19:06:17 +00:00
private void B_JPEG_Click(object sender, EventArgs e)
{
2016-03-05 06:09:54 +00:00
byte[] jpeg = SAV.JPEGData;
if (SAV.JPEGData == null)
{ Util.Alert("No PGL picture data found in the save file!"); return; }
string filename = SAV.JPEGTitle + "'s picture";
SaveFileDialog sfd = new SaveFileDialog {FileName = filename, Filter = "JPEG|*.jpeg"};
if (sfd.ShowDialog() != DialogResult.OK) return;
File.WriteAllBytes(sfd.FileName, jpeg);
2014-12-14 19:06:17 +00:00
}
// Save Folder Related
2014-12-14 19:06:17 +00:00
private void clickSaveFileName(object sender, EventArgs e)
2014-12-13 22:48:34 +00:00
{
string path = SaveUtil.detectSaveFile();
if (path == null || !File.Exists(path)) return;
if (Util.Prompt(MessageBoxButtons.YesNo, "Open save file from the following location?", path) == DialogResult.Yes)
openQuick(path); // load save
}
// Drag and drop related functions
private void pbBoxSlot_MouseClick(object sender, MouseEventArgs e)
{
if (DragInfo.slotDragDropInProgress)
return;
clickSlot(sender, e);
}
private void pbBoxSlot_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
DragInfo.slotLeftMouseIsDown = false;
if (e.Button == MouseButtons.Right)
DragInfo.slotRightMouseIsDown = false;
}
private void pbBoxSlot_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
DragInfo.slotLeftMouseIsDown = true;
if (e.Button == MouseButtons.Right)
DragInfo.slotRightMouseIsDown = true;
}
private void pbBoxSlot_MouseMove(object sender, MouseEventArgs e)
{
if (DragInfo.slotDragDropInProgress)
return;
if (DragInfo.slotLeftMouseIsDown)
{
// The goal is to create a temporary PKX file for the underlying Pokemon
// and use that file to perform a drag drop operation.
// Abort if there is no Pokemon in the given slot.
PictureBox pb = (PictureBox)sender;
if (pb.Image == null)
return;
// Set flag to prevent re-entering.
DragInfo.slotDragDropInProgress = true;
DragInfo.slotSource = this;
DragInfo.slotSourceSlotNumber = getSlot(pb);
int offset = getPKXOffset(DragInfo.slotSourceSlotNumber);
// Prepare Data
DragInfo.slotPkmSource = SAV.getData(offset, SAV.SIZE_STORED);
DragInfo.slotSourceOffset = offset;
DragInfo.slotSourceBoxNumber = DragInfo.slotSourceSlotNumber >= 30 ? -1 : CB_BoxSelect.SelectedIndex;
// Make a new file name based off the PID
bool encrypt = ModifierKeys == Keys.Control;
byte[] dragdata = SAV.decryptPKM(DragInfo.slotPkmSource);
Array.Resize(ref dragdata, SAV.SIZE_STORED);
PKM pkx = SAV.getPKM(dragdata);
string filename = $"{Path.GetFileNameWithoutExtension(pkx.FileName)}{(encrypt ? ".ek" + pkx.Format : "." + pkx.Extension) }";
// Make File
string newfile = Path.Combine(Path.GetTempPath(), Util.CleanFileName(filename));
try
{
File.WriteAllBytes(newfile, encrypt ? pkx.EncryptedBoxData : pkx.DecryptedBoxData);
var img = (Bitmap)pb.Image;
DragInfo.Cursor = Cursor.Current = new Cursor(img.GetHicon());
pb.Image = null;
pb.BackgroundImage = Properties.Resources.slotDrag;
// Thread Blocks on DoDragDrop
DragInfo.CurrentPath = newfile;
DragDropEffects result = pb.DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Move);
if (!DragInfo.SourceValid || result != DragDropEffects.Link) // not dropped to another box slot, restore img
pb.Image = img;
else // refresh image
getQuickFiller(pb, SAV.getStoredSlot(DragInfo.slotSourceOffset));
pb.BackgroundImage = null;
if (DragInfo.slotDestinationBoxNumber == DragInfo.slotSourceBoxNumber && DragInfo.slotDestinationSlotNumber > -1)
SlotPictureBoxes[DragInfo.slotDestinationSlotNumber].Image = img;
if (result == DragDropEffects.Copy) // viewed in tabs, apply 'view' highlight
getSlotColor(DragInfo.slotSourceSlotNumber, Properties.Resources.slotView);
}
catch (Exception x)
{
Util.Error("Drag & Drop Error", x);
}
notifyBoxViewerRefresh();
DragInfo.Reset();
Cursor = DefaultCursor;
// Browser apps need time to load data since the file isn't moved to a location on the user's local storage.
// Tested 10ms -> too quick, 100ms was fine. 500ms should be safe?
new Thread(() =>
{
Thread.Sleep(500);
if (File.Exists(newfile) && DragInfo.CurrentPath == null)
File.Delete(newfile);
}).Start();
}
}
private void pbBoxSlot_DragDrop(object sender, DragEventArgs e)
{
DragInfo.slotDestination = this;
DragInfo.slotDestinationSlotNumber = getSlot(sender);
DragInfo.slotDestinationOffset = getPKXOffset(DragInfo.slotDestinationSlotNumber);
DragInfo.slotDestinationBoxNumber = CB_BoxSelect.SelectedIndex;
// Check for In-Dropped files (PKX,SAV,ETC)
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (Directory.Exists(files[0])) { loadBoxesFromDB(files[0]); return; }
if (DragInfo.slotSourceOffset < 0) // file
{
if (files.Length <= 0)
return;
string file = files[0];
FileInfo fi = new FileInfo(file);
if (!PKX.getIsPKM(fi.Length) && !MysteryGift.getIsMysteryGift(fi.Length))
{ openQuick(file); return; }
byte[] data = File.ReadAllBytes(file);
MysteryGift mg = MysteryGift.getMysteryGift(data, fi.Extension);
PKM temp = mg != null ? mg.convertToPKM(SAV) : PKMConverter.getPKMfromBytes(data);
string c;
PKM pk = PKMConverter.convertToFormat(temp, SAV.PKMType, out c);
if (pk == null)
{ Util.Error(c); Console.WriteLine(c); return; }
string[] errata = verifyPKMtoSAV(pk);
if (errata.Length > 0)
{
string concat = string.Join(Environment.NewLine, errata);
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, concat, "Continue?"))
{ Console.WriteLine(c); Console.WriteLine(concat); return; }
}
SAV.setStoredSlot(pk, DragInfo.slotDestinationOffset);
getQuickFiller(SlotPictureBoxes[DragInfo.slotDestinationSlotNumber], pk);
getSlotColor(DragInfo.slotDestinationSlotNumber, Properties.Resources.slotSet);
Console.WriteLine(c);
}
else
{
PKM pkz = SAV.getStoredSlot(DragInfo.slotSourceOffset);
if (!DragInfo.SourceValid) { } // not overwritable, do nothing
else if (ModifierKeys == Keys.Alt && DragInfo.DestinationValid) // overwrite delete old slot
{
// Clear from slot
if (DragInfo.SameBox)
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], SAV.BlankPKM); // picturebox
SAV.setStoredSlot(SAV.BlankPKM, DragInfo.slotSourceOffset);
}
else if (ModifierKeys != Keys.Control && DragInfo.DestinationValid)
{
// Load data from destination
PKM pk = ((PictureBox) sender).Image != null
? SAV.getStoredSlot(DragInfo.slotDestinationOffset)
: SAV.BlankPKM;
// Set destination pokemon image to source picture box
if (DragInfo.SameBox)
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], pk);
// Set destination pokemon data to source slot
SAV.setStoredSlot(pk, DragInfo.slotSourceOffset);
}
else if (DragInfo.SameBox)
getQuickFiller(SlotPictureBoxes[DragInfo.slotSourceSlotNumber], pkz);
// Copy from temp to destination slot.
SAV.setStoredSlot(pkz, DragInfo.slotDestinationOffset);
getQuickFiller(SlotPictureBoxes[DragInfo.slotDestinationSlotNumber], pkz);
e.Effect = DragDropEffects.Link;
Cursor = DefaultCursor;
}
if (DragInfo.slotSource == null) // another instance or file
{
notifyBoxViewerRefresh();
DragInfo.Reset();
}
}
private void pbBoxSlot_DragEnter(object sender, DragEventArgs e)
{
if (e.AllowedEffect == (DragDropEffects.Copy | DragDropEffects.Link)) // external file
e.Effect = DragDropEffects.Copy;
else if (e.Data != null) // within
e.Effect = DragDropEffects.Move;
if (DragInfo.slotDragDropInProgress)
Cursor = DragInfo.Cursor;
}
private void pbBoxSlot_QueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
if (e.Action == DragAction.Cancel || e.Action == DragAction.Drop)
{
DragInfo.slotLeftMouseIsDown = false;
DragInfo.slotRightMouseIsDown = false;
DragInfo.slotDragDropInProgress = false;
}
}
public static class DragInfo
{
public static bool slotLeftMouseIsDown;
public static bool slotRightMouseIsDown;
public static bool slotDragDropInProgress;
public static byte[] slotPkmSource;
public static byte[] slotPkmDestination;
public static object slotSource;
public static int slotSourceOffset = -1;
public static int slotSourceSlotNumber = -1;
public static int slotSourceBoxNumber = -1;
public static object slotDestination;
public static int slotDestinationOffset = -1;
public static int slotDestinationSlotNumber = -1;
public static int slotDestinationBoxNumber = -1;
public static Cursor Cursor;
public static string CurrentPath;
public static bool SameBox => slotSourceBoxNumber > -1 && slotSourceBoxNumber == slotDestinationBoxNumber;
public static bool SourceValid => slotSourceBoxNumber > -1;
public static bool DestinationValid => slotDestinationBoxNumber > -1;
public static void Reset()
{
slotLeftMouseIsDown = false;
slotRightMouseIsDown = false;
slotDragDropInProgress = false;
slotPkmSource = null;
slotSourceOffset = slotSourceSlotNumber = slotSourceBoxNumber = -1;
slotPkmDestination = null;
slotDestinationOffset = slotSourceBoxNumber = slotDestinationBoxNumber = -1;
Cursor = null;
CurrentPath = null;
slotSource = null;
slotDestination = null;
}
public static bool? WasDragParticipant(object form, int index)
{
if (slotDestinationBoxNumber != index)
return null; // form was not watching box
return slotSource == form || slotDestination == form; // form already updated?
}
}
2014-12-13 22:48:34 +00:00
#endregion
2014-06-28 21:22:05 +00:00
}
}