2017-01-08 07:54:09 +00:00
using System ;
2014-06-28 21:22:05 +00:00
using System.Collections.Generic ;
2016-01-03 04:22:53 +00:00
using System.Diagnostics ;
2014-06-28 21:22:05 +00:00
using System.Drawing ;
2016-08-31 04:12:47 +00:00
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 ;
2016-01-03 18:47:44 +00:00
using System.Media ;
2015-02-13 04:26:23 +00:00
using System.Text ;
using System.Threading ;
using System.Windows.Forms ;
2017-01-08 07:54:09 +00:00
using PKHeX.Core ;
2017-01-14 21:10:36 +00:00
using PKHeX.Core.Properties ;
2017-03-02 15:28:33 +00:00
using System.Configuration ;
2017-03-24 17:59:45 +00:00
using System.Threading.Tasks ;
2014-06-28 21:22:05 +00:00
2017-01-08 07:54:09 +00:00
namespace PKHeX.WinForms
2014-06-28 21:22:05 +00:00
{
2015-09-21 03:34:09 +00:00
public partial class Main : Form
2014-06-28 21:22:05 +00:00
{
2015-09-21 03:34:09 +00:00
public Main ( )
2014-06-28 21:22:05 +00:00
{
#region Initialize Form
2016-01-24 18:19:30 +00:00
new Thread ( ( ) = > new SplashScreen ( ) . ShowDialog ( ) ) . Start ( ) ;
2016-08-26 01:50:51 +00:00
DragInfo . slotPkmSource = SAV . BlankPKM . EncryptedPartyData ;
2014-06-28 21:22:05 +00:00
InitializeComponent ( ) ;
2016-08-31 04:12:47 +00:00
// Check for Updates
2016-10-16 04:28:14 +00:00
L_UpdateAvailable . Click + = ( sender , e ) = > Process . Start ( ThreadPath ) ;
2016-08-31 04:12:47 +00:00
new Thread ( ( ) = >
{
2017-01-12 01:55:42 +00:00
string data = NetUtil . getStringFromURL ( VersionPath ) ;
2016-08-31 04:12:47 +00:00
if ( data = = null )
return ;
try
{
DateTime upd = DateTime . ParseExact ( data , "yyyyMMdd" , CultureInfo . InvariantCulture , DateTimeStyles . None ) ;
2017-01-14 21:10:36 +00:00
DateTime cur = DateTime . ParseExact ( Resources . ProgramVersion , "yyyyMMdd" , CultureInfo . InvariantCulture , DateTimeStyles . None ) ;
2016-08-31 04:12:47 +00:00
if ( upd < = cur )
return ;
2016-12-08 06:57:08 +00:00
string message = $"New Update Available! {upd:d}" ;
2016-08-31 04:12:47 +00:00
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 ( ) ;
2017-01-15 00:43:16 +00:00
setPKMFormatMode ( SAV . Generation , SAV . Version ) ;
2016-06-20 04:22:43 +00:00
// Set up form properties and arrays.
2015-09-21 03:34:09 +00:00
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 ,
} ;
2016-03-15 06:26:29 +00:00
relearnPB = new [ ] { PB_WarnRelearn1 , PB_WarnRelearn2 , PB_WarnRelearn3 , PB_WarnRelearn4 } ;
movePB = new [ ] { PB_WarnMove1 , PB_WarnMove2 , PB_WarnMove3 , PB_WarnMove4 } ;
2016-09-06 06:13:46 +00:00
Label_Species . ResetForeColor ( ) ;
2015-11-19 05:37:30 +00:00
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
2015-11-19 05:37:30 +00:00
// ToolTips for Drag&Drop
2016-06-20 04:22:43 +00:00
new ToolTip ( ) . SetToolTip ( dragout , "PKM QuickSave" ) ;
2015-11-19 05:37:30 +00:00
// Box Drag & Drop
2016-09-12 01:57:12 +00:00
foreach ( PictureBox pb in SlotPictureBoxes )
2015-11-22 18:45:44 +00:00
{
2016-06-20 04:22:43 +00:00
pb . AllowDrop = true ; // The PictureBoxes have their own drag&drop event handlers (pbBoxSlot)
2016-08-21 07:17:45 +00:00
pb . GiveFeedback + = ( sender , e ) = > { e . UseDefaultCursors = false ; } ;
2015-11-22 18:45:44 +00:00
}
2016-08-21 07:17:45 +00:00
dragout . GiveFeedback + = ( sender , e ) = > { e . UseDefaultCursors = false ; } ;
GiveFeedback + = ( sender , e ) = > { e . UseDefaultCursors = false ; } ;
2015-11-22 18:45:44 +00:00
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 ;
}
2015-11-19 05:37:30 +00:00
2016-06-20 04:22:43 +00:00
GB_OT . Click + = clickGT ;
GB_nOT . Click + = clickGT ;
GB_Daycare . Click + = switchDaycare ;
2016-11-15 06:13:15 +00:00
GB_CurrentMoves . Click + = clickMoves ;
2016-06-20 04:22:43 +00:00
GB_RelearnMoves . Click + = clickMoves ;
2017-01-08 07:54:09 +00:00
TB_Nickname . Font = FontUtil . getPKXFont ( 11 ) ;
2016-06-20 04:22:43 +00:00
TB_OT . Font = ( Font ) TB_Nickname . Font . Clone ( ) ;
TB_OTt2 . Font = ( Font ) TB_Nickname . Font . Clone ( ) ;
2016-03-23 03:14:11 +00:00
2016-03-23 03:30:48 +00:00
Menu_Modify . DropDown . Closing + = ( sender , e ) = >
2016-03-23 03:14:11 +00:00
{
if ( e . CloseReason = = ToolStripDropDownCloseReason . ItemClicked )
e . Cancel = true ;
} ;
2016-09-30 05:41:35 +00:00
Menu_Options . DropDown . Closing + = ( sender , e ) = >
{
if ( ! Menu_Unicode . Selected )
return ;
if ( e . CloseReason = = ToolStripDropDownCloseReason . ItemClicked )
e . Cancel = true ;
} ;
2016-06-20 04:22:43 +00:00
// Box to Tabs D&D
dragout . AllowDrop = true ;
2017-01-08 07:54:09 +00:00
FLP_SAVtools . Scroll + = WinFormsUtil . PanelScroll ;
2016-07-29 23:00:56 +00:00
2017-01-28 21:07:44 +00:00
// Add Legality check to right click context menus
// ToolStripItem can't be in multiple contextmenus, so put the item back when closing.
var cm = new [ ] { mnuV , mnuVSD } ;
foreach ( var c in cm )
{
c . Opening + = ( sender , e ) = >
{
2017-01-28 23:20:11 +00:00
var items = ( ( ContextMenuStrip ) sender ) . Items ;
2017-01-28 21:07:44 +00:00
if ( ModifierKeys = = Keys . Control )
2017-01-28 23:20:11 +00:00
items . Add ( mnuLLegality ) ;
else if ( items . Contains ( mnuLLegality ) )
items . Remove ( mnuLLegality ) ;
2017-01-28 21:07:44 +00:00
} ;
}
2017-01-28 23:20:11 +00:00
mnuL . Opening + = ( sender , e ) = >
{
if ( mnuL . Items [ 0 ] ! = mnuLLegality )
mnuL . Items . Insert ( 0 , mnuLLegality ) ;
} ;
2017-01-28 21:07:44 +00:00
2017-03-19 23:19:59 +00:00
// Load Event Databases
2017-04-19 10:15:50 +00:00
refreshMGDB ( ) ;
2016-06-20 04:22:43 +00:00
2015-11-19 05:37:30 +00:00
#endregion
#region Localize & Populate Fields
2016-06-20 04:22:43 +00:00
string [ ] args = Environment . GetCommandLineArgs ( ) ;
2016-07-18 18:51:26 +00:00
string filename = args . Length > 0 ? Path . GetFileNameWithoutExtension ( args [ 0 ] ) ? . ToLower ( ) : "" ;
2016-09-30 05:41:35 +00:00
HaX = filename ? . IndexOf ( "hax" , StringComparison . Ordinal ) > = 0 ;
2016-06-20 04:22:43 +00:00
2016-09-30 05:41:35 +00:00
bool showChangelog = false ;
2016-12-04 19:23:10 +00:00
bool BAKprompt = false ;
2017-01-10 03:15:46 +00:00
int languageID = 1 ; // English
try
{
ConfigUtil . checkConfig ( ) ;
loadConfig ( out BAKprompt , out showChangelog , out languageID ) ;
}
2017-03-02 15:28:33 +00:00
catch ( ConfigurationErrorsException e )
2017-01-10 03:15:46 +00:00
{
2017-03-02 15:28:33 +00:00
// Delete the settings if they exist
var settingsFilename = ( e . InnerException as ConfigurationErrorsException ) ? . Filename ;
2017-03-02 15:40:33 +00:00
if ( ! string . IsNullOrEmpty ( settingsFilename ) & & File . Exists ( settingsFilename ) )
2017-03-05 01:21:33 +00:00
deleteConfig ( settingsFilename ) ;
2017-03-02 15:28:33 +00:00
else
WinFormsUtil . Error ( "Unable to load settings." , e ) ;
2017-01-10 03:15:46 +00:00
}
CB_MainLanguage . SelectedIndex = languageID ;
2014-08-17 01:42:51 +00:00
2015-09-25 02:54:50 +00:00
InitializeFields ( ) ;
2016-10-29 22:41:55 +00:00
2014-06-28 21:22:05 +00:00
#endregion
2015-11-19 05:37:30 +00:00
#region Load Initial File ( s )
2017-02-05 21:24:39 +00:00
string pkmArg = null ;
foreach ( string arg in args . Skip ( 1 ) ) // skip .exe
2015-09-13 16:10:44 +00:00
{
2017-02-05 21:24:39 +00:00
var fi = new FileInfo ( arg ) ;
if ( ! fi . Exists )
continue ;
if ( PKX . getIsPKM ( fi . Length ) )
pkmArg = arg ;
else
2016-06-20 04:22:43 +00:00
openQuick ( arg , force : true ) ;
2015-09-13 16:10:44 +00:00
}
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
{
2016-08-22 01:05:41 +00:00
string path = null ;
try
{
2017-01-08 07:54:09 +00:00
string cgse = "" ;
string pathCache = CyberGadgetUtil . GetCacheFolder ( ) ;
if ( Directory . Exists ( pathCache ) )
cgse = Path . Combine ( pathCache ) ;
if ( ! SaveUtil . detectSaveFile ( out path , cgse ) )
WinFormsUtil . Error ( path ) ;
2016-08-22 01:05:41 +00:00
}
catch ( Exception ex )
{
ErrorWindow . ShowErrorDialog ( "An error occurred while attempting to auto-load your save file." , ex , true ) ;
}
2016-08-02 03:38:55 +00:00
if ( path ! = null & & File . Exists ( path ) )
2016-06-20 04:22:43 +00:00
openQuick ( path , force : true ) ;
2016-07-04 23:16:34 +00:00
else
2016-10-20 00:47:43 +00:00
{
2016-10-12 02:11:24 +00:00
openSAV ( SAV , null ) ;
2016-10-20 00:47:43 +00:00
SAV . Edited = false ; // Prevents form close warning from showing until changes are made
}
2016-04-06 03:37:36 +00:00
}
2017-02-05 21:24:39 +00:00
if ( pkmArg ! = null )
openQuick ( pkmArg , force : true ) ;
2015-02-28 03:03:36 +00:00
2017-03-30 05:23:18 +00:00
formInitialized = true ; // Splash Screen closes on its own.
2015-03-11 01:44:51 +00:00
BringToFront ( ) ;
WindowState = FormWindowState . Minimized ;
Show ( ) ;
WindowState = FormWindowState . Normal ;
2017-01-08 07:54:09 +00:00
if ( HaX ) WinFormsUtil . Alert ( "Illegal mode activated." , "Please behave." ) ;
2016-09-30 05:41:35 +00:00
if ( showChangelog )
new About ( ) . ShowDialog ( ) ;
2016-12-04 19:23:10 +00:00
if ( BAKprompt & & ! Directory . Exists ( BackupPath ) )
promptBackup ( ) ;
2014-06-28 21:22:05 +00:00
#endregion
}
2016-02-17 15:54:59 +00:00
#region Important Variables
2017-01-15 00:43:16 +00:00
public static SaveFile SAV = SaveUtil . getBlankSAV ( GameVersion . SN , "PKHeX" ) ;
2016-11-13 04:44:51 +00:00
public static PKM pkm = SAV . BlankPKM ; // Tab Pokemon Data Storage
private LegalityAnalysis Legality = new LegalityAnalysis ( pkm ) ;
2016-07-31 21:40:09 +00:00
2016-06-20 04:22:43 +00:00
public static string curlanguage = "en" ;
2016-02-17 15:54:59 +00:00
public static string [ ] gendersymbols = { "♂" , "♀" , "-" } ;
public static bool unicode ;
2017-03-22 06:25:13 +00:00
public static volatile bool formInitialized ;
private static bool fieldsInitialized , fieldsLoaded , loadingSAV ;
2016-06-20 04:22:43 +00:00
private static int colorizedbox = - 1 ;
2016-02-17 15:54:59 +00:00
private static Image colorizedcolor ;
private static int colorizedslot ;
2016-09-28 06:53:53 +00:00
public static bool HaX ;
2017-01-14 21:10:36 +00:00
private static readonly Image mixedHighlight = ImageUtil . ChangeOpacity ( Resources . slotSet , 0.5 ) ;
2016-04-10 16:33:38 +00:00
private static readonly string [ ] main_langlist =
2015-03-12 05:51:56 +00:00
{
"日本語" , // JPN
2016-04-10 16:33:38 +00:00
"English" , // ENG
2015-03-12 05:51:56 +00:00
"Français" , // FRE
"Italiano" , // ITA
"Deutsch" , // GER
"Español" , // SPA
"한국어" , // KOR
"中文" , // CHN
"Português" , // Portuguese
} ;
2016-08-27 20:05:01 +00:00
private static GameVersion origintrack ;
2016-03-15 06:26:29 +00:00
private readonly PictureBox [ ] SlotPictureBoxes , movePB , relearnPB ;
2016-12-31 01:23:59 +00:00
private readonly ToolTip Tip1 = new ToolTip ( ) , Tip2 = new ToolTip ( ) , Tip3 = new ToolTip ( ) , NatureTip = new ToolTip ( ) , EVTip = new ToolTip ( ) ;
2014-06-28 21:22:05 +00:00
#endregion
2014-12-13 22:48:34 +00:00
2016-07-31 21:40:09 +00:00
#region Path Variables
2017-03-19 17:42:48 +00:00
public static string WorkingDirectory = > WinFormsUtil . IsClickonceDeployed ? Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . MyDocuments ) , "PKHeX" ) : Application . StartupPath ;
2016-11-13 21:11:53 +00:00
public static string DatabasePath = > Path . Combine ( WorkingDirectory , "pkmdb" ) ;
public static string MGDatabasePath = > Path . Combine ( WorkingDirectory , "mgdb" ) ;
2016-08-01 01:15:58 +00:00
private static string BackupPath = > Path . Combine ( WorkingDirectory , "bak" ) ;
2017-05-11 02:24:58 +00:00
private static string TemplatePath = > Path . Combine ( WorkingDirectory , "template" ) ;
2017-01-26 06:51:52 +00:00
private const string ThreadPath = @"https://projectpokemon.org/PKHeX/" ;
private const string VersionPath = @"https://raw.githubusercontent.com/kwsch/PKHeX/master/PKHeX/Resources/text/version.txt" ;
2016-07-31 21:40:09 +00:00
#endregion
2014-12-13 22:48:34 +00:00
#region //// MAIN MENU FUNCTIONS ////
2017-01-10 03:15:46 +00:00
private void loadConfig ( out bool BAKprompt , out bool showChangelog , out int languageID )
2016-12-07 07:29:57 +00:00
{
BAKprompt = false ;
showChangelog = false ;
2017-01-10 03:15:46 +00:00
languageID = 1 ;
var Settings = Properties . Settings . Default ;
Settings . Upgrade ( ) ;
unicode = Menu_Unicode . Checked = Settings . Unicode ;
2016-12-07 07:29:57 +00:00
updateUnicode ( ) ;
2017-01-10 03:15:46 +00:00
SaveFile . SetUpdateDex = Menu_ModifyDex . Checked = Settings . SetUpdateDex ;
SaveFile . SetUpdatePKM = Menu_ModifyPKM . Checked = Settings . SetUpdatePKM ;
2017-02-05 04:39:42 +00:00
Menu_FlagIllegal . Checked = Settings . FlagIllegal ;
2017-03-23 01:02:05 +00:00
Menu_ModifyUnset . Checked = Settings . ModifyUnset ;
2016-12-07 07:29:57 +00:00
// Select Language
2017-01-10 03:15:46 +00:00
string l = Settings . Language ;
2016-12-07 07:29:57 +00:00
int lang = Array . IndexOf ( GameInfo . lang_val , l ) ;
2017-03-20 07:03:31 +00:00
if ( lang < 0 )
lang = Array . IndexOf ( GameInfo . lang_val , "en" ) ;
2017-01-23 07:05:54 +00:00
if ( lang > - 1 )
languageID = lang ;
2016-12-07 07:29:57 +00:00
// Version Check
2017-01-10 03:15:46 +00:00
if ( Settings . Version . Length > 0 ) // already run on system
2016-12-07 07:29:57 +00:00
{
2017-01-10 03:15:46 +00:00
int lastrev ; int . TryParse ( Settings . Version , out lastrev ) ;
2017-01-14 21:10:36 +00:00
int currrev ; int . TryParse ( Resources . ProgramVersion , out currrev ) ;
2016-12-07 07:29:57 +00:00
showChangelog = lastrev < currrev ;
}
// BAK Prompt
2017-01-10 03:15:46 +00:00
if ( ! Settings . BAKPrompt )
BAKprompt = Settings . BAKPrompt = true ;
2016-12-07 07:29:57 +00:00
2017-01-14 21:10:36 +00:00
Settings . Version = Resources . ProgramVersion ;
2016-12-07 07:29:57 +00:00
}
2017-03-05 01:21:33 +00:00
private static void deleteConfig ( string settingsFilename )
{
var dr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "PKHeX's settings are corrupt. Would you like to reset the settings?" ,
"Yes to delete the settings or No to close the program." ) ;
if ( dr = = DialogResult . Yes )
{
File . Delete ( settingsFilename ) ;
WinFormsUtil . Alert ( "The settings have been deleted" , "Please restart the program." ) ;
}
Process . GetCurrentProcess ( ) . Kill ( ) ;
}
2014-12-13 22:48:34 +00:00
// Main Menu Strip UI Functions
2014-12-14 07:18:27 +00:00
private void mainMenuOpen ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2016-08-03 01:46:41 +00:00
string pkx = pkm . Extension ;
string ekx = 'e' + pkx . Substring ( 1 , pkx . Length - 1 ) ;
2017-01-05 06:22:50 +00:00
string supported = string . Join ( ";" , SAV . PKMExtensions . Select ( s = > "*." + s ) . Concat ( new [ ] { "*.pkm" } ) ) ;
2015-09-27 17:00:45 +00:00
OpenFileDialog ofd = new OpenFileDialog
{
2017-02-10 04:19:38 +00:00
Filter = "All Files|*.*" +
2017-02-22 06:23:20 +00:00
$"|Supported Files|main;*.sav;*.dat;*.gci;*.bin;*.{ekx};{supported};*.bak" +
2017-01-08 08:14:34 +00:00
"|3DS Main Files|main" +
2017-02-22 08:15:30 +00:00
"|Save Files|*.sav;*.dat;*.gci" +
2017-01-02 16:51:23 +00:00
$"|Decrypted PKM File|{supported}" +
2016-08-03 01:46:41 +00:00
$"|Encrypted PKM File|*.{ekx}" +
"|Binary File|*.bin" +
2017-02-10 04:19:38 +00:00
"|Backup File|*.bak"
2017-01-08 07:54:09 +00:00
} ;
2016-03-30 17:14:32 +00:00
2016-02-01 07:15:54 +00:00
// Detect main
2017-01-08 07:54:09 +00:00
string cgse = "" ;
string path ;
string pathCache = CyberGadgetUtil . GetCacheFolder ( ) ;
if ( Directory . Exists ( pathCache ) )
cgse = Path . Combine ( pathCache ) ;
if ( ! SaveUtil . detectSaveFile ( out path , cgse ) )
WinFormsUtil . Error ( path ) ;
2016-06-20 04:22:43 +00:00
if ( path ! = null )
2017-01-02 16:51:23 +00:00
{ ofd . FileName = path ; }
2015-03-12 04:44:12 +00:00
2016-02-01 07:15:54 +00:00
if ( ofd . ShowDialog ( ) = = DialogResult . OK )
openQuick ( ofd . FileName ) ;
2014-06-28 21:22:05 +00:00
}
2014-12-14 07:18:27 +00:00
private void mainMenuSave ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) ) return ;
2016-06-20 04:22:43 +00:00
PKM pk = preparePKM ( ) ;
2016-08-03 01:46:41 +00:00
string pkx = pk . Extension ;
string ekx = 'e' + pkx . Substring ( 1 , pkx . Length - 1 ) ;
2015-09-27 17:00:45 +00:00
SaveFileDialog sfd = new SaveFileDialog
{
2016-08-03 01:46:41 +00:00
Filter = $"Decrypted PKM File|*.{pkx}" +
2016-08-29 05:21:55 +00:00
( SAV . Generation > 2 ? "" : $"|Encrypted PKM File|*.{ekx}" ) +
2016-08-03 01:46:41 +00:00
"|Binary File|*.bin" +
2015-09-27 17:00:45 +00:00
"|All Files|*.*" ,
2016-08-03 01:46:41 +00:00
DefaultExt = pkx ,
2016-04-22 01:47:51 +00:00
FileName = Util . CleanFileName ( pk . FileName )
2015-09-27 17:00:45 +00:00
} ;
if ( sfd . ShowDialog ( ) ! = DialogResult . OK ) return ;
string path = sfd . FileName ;
2015-03-11 01:44:51 +00:00
string ext = Path . GetExtension ( path ) ;
2014-06-28 21:22:05 +00:00
2016-08-03 01:46:41 +00:00
if ( File . Exists ( path ) )
2015-03-11 01:44:51 +00:00
{
// File already exists, save a .bak
2017-01-05 06:22:50 +00:00
string bakpath = path + ".bak" ;
if ( ! File . Exists ( bakpath ) )
{
byte [ ] backupfile = File . ReadAllBytes ( path ) ;
File . WriteAllBytes ( bakpath , backupfile ) ;
}
2015-03-11 01:44:51 +00:00
}
2014-06-28 21:22:05 +00:00
2016-08-04 00:48:13 +00:00
if ( new [ ] { ".ekx" , "." + ekx , ".bin" } . Contains ( ext ) )
2016-01-24 18:19:30 +00:00
File . WriteAllBytes ( path , pk . EncryptedPartyData ) ;
2016-08-04 00:48:13 +00:00
else if ( new [ ] { "." + pkx } . Contains ( ext ) )
2016-08-03 01:46:41 +00:00
File . WriteAllBytes ( path , pk . DecryptedBoxData ) ;
2015-03-11 01:44:51 +00:00
else
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( $"Foreign File Extension: {ext}" , "Exporting as encrypted." ) ;
2016-06-20 04:22:43 +00:00
File . WriteAllBytes ( path , pkm . EncryptedPartyData ) ;
2014-06-28 21:22:05 +00:00
}
2014-12-13 22:48:34 +00:00
}
2014-12-14 07:18:27 +00:00
private void mainMenuExit ( object sender , EventArgs e )
2014-12-13 22:48:34 +00:00
{
2016-08-11 04:10:21 +00:00
if ( ModifierKeys = = Keys . Control ) // Hotkey Triggered
2017-01-09 01:14:39 +00:00
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Quit PKHeX?" ) ) return ;
2015-03-11 01:44:51 +00:00
Close ( ) ;
2014-12-13 22:48:34 +00:00
}
2014-12-14 07:18:27 +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 ( ) ;
}
2016-01-03 04:22:53 +00:00
// Sub Menu Options
2014-12-14 07:18:27 +00:00
private void mainMenuBoxReport ( object sender , EventArgs e )
2014-12-13 22:48:34 +00:00
{
2016-04-15 23:11:46 +00:00
var z = Application . OpenForms . Cast < Form > ( ) . FirstOrDefault ( form = > form . GetType ( ) = = typeof ( frmReport ) ) as frmReport ;
2016-04-08 05:16:08 +00:00
if ( z ! = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . CenterToForm ( z , this ) ; z . BringToFront ( ) ; return ; }
2016-06-20 04:22:43 +00:00
2014-12-13 22:48:34 +00:00
frmReport ReportForm = new frmReport ( ) ;
2015-02-11 22:47:59 +00:00
ReportForm . Show ( ) ;
2016-06-20 04:22:43 +00:00
ReportForm . PopulateData ( SAV . BoxData ) ;
2014-12-13 22:48:34 +00:00
}
2016-01-30 02:02:54 +00:00
private void mainMenuDatabase ( object sender , EventArgs e )
{
2016-11-12 18:19:17 +00:00
if ( ModifierKeys = = Keys . Shift )
{
var c = Application . OpenForms . Cast < Form > ( ) . FirstOrDefault ( form = > form . GetType ( ) = = typeof ( KChart ) ) as KChart ;
if ( c ! = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . CenterToForm ( c , this ) ; c . BringToFront ( ) ; }
2016-11-12 18:19:17 +00:00
else
new KChart ( ) . Show ( ) ;
return ;
}
2016-04-15 23:11:46 +00:00
var z = Application . OpenForms . Cast < Form > ( ) . FirstOrDefault ( form = > form . GetType ( ) = = typeof ( SAV_Database ) ) as SAV_Database ;
2016-04-08 05:16:08 +00:00
if ( z ! = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . CenterToForm ( z , this ) ; z . BringToFront ( ) ; return ; }
2016-01-30 02:02:54 +00:00
2016-08-11 02:44:47 +00:00
if ( Directory . Exists ( DatabasePath ) )
2016-01-30 02:02:54 +00:00
new SAV_Database ( this ) . Show ( ) ;
else
2017-01-08 23:27:00 +00:00
WinFormsUtil . Alert ( "PKHeX's database was not found." ,
2016-08-11 02:44:47 +00:00
$"Please dump all boxes from a save file, then ensure the '{DatabasePath}' folder exists." ) ;
2016-01-30 02:02:54 +00:00
}
2016-09-04 17:38:53 +00:00
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 )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . CenterToForm ( z , this ) ; z . BringToFront ( ) ; return ; }
2016-09-04 17:38:53 +00:00
new SAV_MysteryGiftDB ( this ) . Show ( ) ;
}
2014-12-13 22:48:34 +00:00
private void mainMenuUnicode ( object sender , EventArgs e )
{
2016-09-30 05:41:35 +00:00
Properties . Settings . Default . Unicode = unicode = Menu_Unicode . Checked ;
2016-01-30 01:27:20 +00:00
updateUnicode ( ) ;
2014-12-13 22:48:34 +00:00
}
2015-10-25 01:16:22 +00:00
private void mainMenuModifyDex ( object sender , EventArgs e )
2015-10-24 03:13:32 +00:00
{
2016-09-30 05:41:35 +00:00
Properties . Settings . Default . SetUpdateDex = SaveFile . SetUpdateDex = Menu_ModifyDex . Checked ;
2015-10-24 03:13:32 +00:00
}
2017-03-23 01:02:05 +00:00
private void mainMenuModifyUnset ( object sender , EventArgs e )
{
Properties . Settings . Default . ModifyUnset = Menu_ModifyUnset . Checked ;
}
2016-06-20 04:22:43 +00:00
private void mainMenuModifyPKM ( object sender , EventArgs e )
2015-10-24 03:13:32 +00:00
{
2016-09-30 05:41:35 +00:00
Properties . Settings . Default . SetUpdatePKM = SaveFile . SetUpdatePKM = Menu_ModifyPKM . Checked ;
2015-10-24 03:13:32 +00:00
}
2017-02-05 04:39:42 +00:00
private void mainMenuFlagIllegal ( object sender , EventArgs e )
{
Properties . Settings . Default . FlagIllegal = Menu_FlagIllegal . Checked ;
updateBoxViewers ( all : true ) ;
setPKXBoxes ( ) ;
}
2016-01-03 04:22:53 +00:00
private void mainMenuBoxLoad ( object sender , EventArgs e )
2015-10-25 01:16:22 +00:00
{
string path = "" ;
2016-01-03 04:22:53 +00:00
if ( Directory . Exists ( DatabasePath ) )
2015-10-25 01:16:22 +00:00
{
2017-01-09 01:14:39 +00:00
DialogResult ld = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Load from PKHeX's database?" ) ;
2016-01-03 04:22:53 +00:00
if ( ld = = DialogResult . Yes )
path = DatabasePath ;
else if ( ld = = DialogResult . No )
2015-10-25 01:16:22 +00:00
{
2016-01-03 04:22:53 +00:00
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog ( ) ;
if ( fbd . ShowDialog ( ) = = DialogResult . OK )
path = fbd . SelectedPath ;
2015-10-25 01:16:22 +00:00
}
2016-01-03 04:22:53 +00:00
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 ;
2017-02-04 22:58:30 +00:00
bool separate = false ;
2016-01-03 04:22:53 +00:00
// Dump all of box content to files.
2017-01-09 01:14:39 +00:00
DialogResult ld = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Save to PKHeX's database?" ) ;
2016-01-03 04:22:53 +00:00
if ( ld = = DialogResult . Yes )
{
path = DatabasePath ;
if ( ! Directory . Exists ( path ) )
Directory . CreateDirectory ( path ) ;
}
else if ( ld = = DialogResult . No )
{
2017-02-04 22:58:30 +00:00
separate = DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Save each box separately?" ) ;
2015-10-25 01:16:22 +00:00
2016-01-03 04:22:53 +00:00
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog ( ) ;
if ( fbd . ShowDialog ( ) ! = DialogResult . OK )
return ;
2015-10-25 01:16:22 +00:00
2016-01-03 04:22:53 +00:00
path = fbd . SelectedPath ;
}
else return ;
2015-10-25 01:16:22 +00:00
2017-02-04 22:58:30 +00:00
string result ;
SAV . dumpBoxes ( path , out result , separate ) ;
WinFormsUtil . Alert ( result ) ;
2016-01-03 04:22:53 +00:00
}
2017-03-21 07:21:03 +00:00
private void mainMenuBoxDumpSingle ( object sender , EventArgs e )
{
// open folder dialog
FolderBrowserDialog fbd = new FolderBrowserDialog ( ) ;
if ( fbd . ShowDialog ( ) ! = DialogResult . OK )
return ;
string result ;
2017-03-22 06:25:13 +00:00
SAV . dumpBox ( fbd . SelectedPath , out result , CB_BoxSelect . SelectedIndex ) ;
2017-03-21 07:21:03 +00:00
WinFormsUtil . Alert ( result ) ;
}
2016-07-13 05:19:51 +00:00
private void manMenuBatchEditor ( object sender , EventArgs e )
{
2017-01-09 05:06:15 +00:00
new BatchEditor ( preparePKM ( ) ) . ShowDialog ( ) ;
2016-07-13 05:19:51 +00:00
setPKXBoxes ( ) ; // refresh
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2016-07-13 05:19:51 +00:00
}
2016-01-03 04:22:53 +00:00
// Misc Options
2016-10-29 22:41:55 +00:00
private void clickShowdownImportPKM ( object sender , EventArgs e )
2016-01-03 04:22:53 +00:00
{
2016-04-05 03:39:11 +00:00
if ( ! formInitialized )
return ;
2016-01-03 04:22:53 +00:00
if ( ! Clipboard . ContainsText ( ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Clipboard does not contain text." ) ; return ; }
2016-01-03 04:22:53 +00:00
// Get Simulator Data
2016-06-20 04:22:43 +00:00
ShowdownSet Set = new ShowdownSet ( Clipboard . GetText ( ) ) ;
2016-01-03 04:22:53 +00:00
if ( Set . Species < 0 )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Set data not found in clipboard." ) ; return ; }
2016-01-03 04:22:53 +00:00
2016-09-20 02:20:55 +00:00
if ( Set . Nickname ! = null & & Set . Nickname . Length > SAV . NickLength )
Set . Nickname = Set . Nickname . Substring ( 0 , SAV . NickLength ) ;
2017-01-08 07:54:09 +00:00
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Import this set?" , Set . getText ( ) ) )
2016-01-03 04:22:53 +00:00
{ return ; }
2016-09-04 06:14:05 +00:00
if ( Set . InvalidLines . Any ( ) )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Invalid lines detected:" , string . Join ( Environment . NewLine , Set . InvalidLines ) ) ;
2016-09-04 06:14:05 +00:00
2016-01-03 04:22:53 +00:00
// Set Species & Nickname
CB_Species . SelectedValue = Set . Species ;
2016-01-05 06:42:38 +00:00
CHK_Nicknamed . Checked = Set . Nickname ! = null ;
2016-01-03 04:22:53 +00:00
if ( Set . Nickname ! = null )
TB_Nickname . Text = Set . Nickname ;
2016-10-16 04:28:14 +00:00
if ( Set . Gender ! = null )
2016-01-03 04:22:53 +00:00
{
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 ) ;
2015-10-25 01:16:22 +00:00
}
2016-01-03 04:22:53 +00:00
// Set Form
string [ ] formStrings = PKX . getFormList ( Set . Species ,
2016-10-06 04:06:24 +00:00
Util . getTypesList ( "en" ) ,
Util . getFormsList ( "en" ) , gendersymbols , SAV . Generation ) ;
2016-01-03 04:22:53 +00:00
int form = 0 ;
for ( int i = 0 ; i < formStrings . Length ; i + + )
if ( formStrings [ i ] . Contains ( Set . Form ? ? "" ) )
{ form = i ; break ; }
2017-01-19 07:18:14 +00:00
CB_Form . SelectedIndex = Math . Min ( CB_Form . Items . Count - 1 , form ) ;
2016-01-03 04:22:53 +00:00
// Set Ability
2016-07-18 06:40:40 +00:00
int [ ] abilities = SAV . Personal . getAbilities ( Set . Species , form ) ;
2016-07-03 03:24:17 +00:00
int ability = Array . IndexOf ( abilities , Set . Ability ) ;
2016-01-03 04:22:53 +00:00
if ( ability < 0 ) ability = 0 ;
CB_Ability . SelectedIndex = ability ;
2016-09-18 05:10:27 +00:00
ComboBox [ ] m = { CB_Move1 , CB_Move2 , CB_Move3 , CB_Move4 } ;
2016-01-03 04:22:53 +00:00
for ( int i = 0 ; i < 4 ; i + + ) m [ i ] . SelectedValue = Set . Moves [ i ] ;
// Set Item and Nature
2016-01-05 06:42:38 +00:00
CB_HeldItem . SelectedValue = Set . Item < 0 ? 0 : Set . Item ;
CB_Nature . SelectedValue = Set . Nature < 0 ? 0 : Set . Nature ;
2016-01-03 04:22:53 +00:00
// Set IVs
TB_HPIV . Text = Set . IVs [ 0 ] . ToString ( ) ;
TB_ATKIV . Text = Set . IVs [ 1 ] . ToString ( ) ;
TB_DEFIV . Text = Set . IVs [ 2 ] . ToString ( ) ;
2016-09-18 05:10:27 +00:00
TB_SPAIV . Text = Set . IVs [ 4 ] . ToString ( ) ;
TB_SPDIV . Text = Set . IVs [ 5 ] . ToString ( ) ;
TB_SPEIV . Text = Set . IVs [ 3 ] . ToString ( ) ;
2016-01-03 04:22:53 +00:00
// Set EVs
TB_HPEV . Text = Set . EVs [ 0 ] . ToString ( ) ;
TB_ATKEV . Text = Set . EVs [ 1 ] . ToString ( ) ;
TB_DEFEV . Text = Set . EVs [ 2 ] . ToString ( ) ;
2016-09-18 05:10:27 +00:00
TB_SPAEV . Text = Set . EVs [ 4 ] . ToString ( ) ;
TB_SPDEV . Text = Set . EVs [ 5 ] . ToString ( ) ;
TB_SPEEV . Text = Set . EVs [ 3 ] . ToString ( ) ;
2016-01-03 04:22:53 +00:00
// Set Level and Friendship
TB_Level . Text = Set . Level . ToString ( ) ;
TB_Friendship . Text = Set . Friendship . ToString ( ) ;
// Reset IV/EVs
2017-02-27 16:59:20 +00:00
updateRandomPID ( sender , e ) ;
updateRandomEC ( sender , e ) ;
2016-09-18 05:10:27 +00:00
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
2017-02-27 16:59:20 +00:00
if ( Set . Shiny ) updateShinyPID ( sender , e ) ;
2016-06-20 04:22:43 +00:00
pkm = preparePKM ( ) ;
2016-03-18 01:58:30 +00:00
updateLegality ( ) ;
2016-01-03 04:22:53 +00:00
}
2016-10-29 22:41:55 +00:00
private void clickShowdownExportPKM ( object sender , EventArgs e )
2016-01-03 04:22:53 +00:00
{
2016-06-20 04:22:43 +00:00
if ( ! formInitialized )
return ;
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Fix data before exporting." ) ; return ; }
2016-01-03 04:22:53 +00:00
2016-06-20 04:22:43 +00:00
Clipboard . SetText ( preparePKM ( ) . ShowdownText ) ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Exported Showdown Set to Clipboard:" , Clipboard . GetText ( ) ) ;
2016-01-03 04:22:53 +00:00
}
private void clickShowdownExportParty ( object sender , EventArgs e )
{
2016-01-27 02:52:08 +00:00
if ( SAV . PartyData . Length < = 0 ) return ;
2016-01-03 04:22:53 +00:00
try
{
Clipboard . SetText (
SAV . PartyData . Aggregate ( "" , ( current , pk ) = > current + pk . ShowdownText
+ Environment . NewLine + Environment . NewLine ) . Trim ( ) ) ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Showdown Team (Party) set to Clipboard." ) ;
2016-01-03 04:22:53 +00:00
}
catch { }
}
private void clickShowdownExportBattleBox ( object sender , EventArgs e )
{
2016-01-27 02:52:08 +00:00
if ( SAV . BattleBoxData . Length < = 0 ) return ;
2016-01-03 04:22:53 +00:00
try
{
Clipboard . SetText (
SAV . BattleBoxData . Aggregate ( "" , ( current , pk ) = > current + pk . ShowdownText
+ Environment . NewLine + Environment . NewLine ) . Trim ( ) ) ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Showdown Team (Battle Box) set to Clipboard." ) ;
2016-01-03 04:22:53 +00:00
}
catch { }
}
private void clickOpenTempFolder ( object sender , EventArgs e )
{
2017-01-08 07:54:09 +00:00
string path = CyberGadgetUtil . GetTempFolder ( ) ;
2016-01-03 04:22:53 +00:00
if ( Directory . Exists ( Path . Combine ( path , "root" ) ) )
2016-07-17 17:06:52 +00:00
Process . Start ( "explorer.exe" , Path . Combine ( path , "root" ) ) ;
2016-01-03 04:22:53 +00:00
else if ( Directory . Exists ( path ) )
2016-07-17 17:06:52 +00:00
Process . Start ( "explorer.exe" , path ) ;
2016-01-03 04:22:53 +00:00
else
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Can't find the temporary file." , "Make sure the Cyber Gadget software is paused." ) ;
2016-01-03 04:22:53 +00:00
}
private void clickOpenCacheFolder ( object sender , EventArgs e )
{
2017-01-08 07:54:09 +00:00
string path = CyberGadgetUtil . GetCacheFolder ( ) ;
2016-01-03 04:22:53 +00:00
if ( Directory . Exists ( path ) )
2016-07-17 17:06:52 +00:00
Process . Start ( "explorer.exe" , path ) ;
2016-01-03 04:22:53 +00:00
else
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Can't find the cache folder." ) ;
2016-01-03 04:22:53 +00:00
}
private void clickOpenSDFFolder ( object sender , EventArgs e )
{
2016-08-05 03:48:52 +00:00
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 ) ;
2016-01-03 04:22:53 +00:00
else
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Can't find the SaveDataFiler folder." ) ;
2016-01-03 04:22:53 +00:00
}
private void clickOpenSDBFolder ( object sender , EventArgs e )
{
2016-08-05 03:48:52 +00:00
string path3DS = Path . GetPathRoot ( Util . get3DSLocation ( ) ) ;
2016-01-03 04:22:53 +00:00
string path ;
2016-08-05 03:48:52 +00:00
if ( path3DS ! = null & & Directory . Exists ( path = Path . Combine ( path3DS , "SaveDataBackup" ) ) )
2016-07-17 17:06:52 +00:00
Process . Start ( "explorer.exe" , path ) ;
2016-01-03 04:22:53 +00:00
else
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Can't find the SaveDataBackup folder." ) ;
2015-10-25 01:16:22 +00:00
}
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Main Menu Subfunctions
2016-06-20 04:22:43 +00:00
private void openQuick ( string path , bool force = false )
2014-12-13 22:48:34 +00:00
{
2016-06-20 04:22:43 +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 ) ;
2017-04-02 14:53:46 +00:00
if ( fi . Length > 0x10009C & & fi . Length ! = 0x380000 & & ! SAV3GCMemoryCard . IsMemoryCardSize ( fi . Length ) )
2017-02-15 16:29:47 +00:00
WinFormsUtil . Error ( "Input file is too large." + Environment . NewLine + $"Size: {fi.Length} bytes" , path ) ;
else if ( fi . Length < 32 )
WinFormsUtil . Error ( "Input file is too small." + Environment . NewLine + $"Size: {fi.Length} bytes" , path ) ;
2014-12-13 22:48:34 +00:00
else
{
byte [ ] input ; try { input = File . ReadAllBytes ( path ) ; }
2017-01-08 07:54:09 +00:00
catch ( Exception e ) { WinFormsUtil . 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
2017-03-18 23:50:34 +00:00
#if DEBUG
openFile ( input , path , ext ) ;
#else
2014-12-13 22:48:34 +00:00
try { openFile ( input , path , ext ) ; }
2017-01-08 07:54:09 +00:00
catch ( Exception e ) { WinFormsUtil . Error ( "Unable to load file.\nPath: " + path , e ) ; }
2017-03-18 23:50:34 +00:00
#endif
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 )
{
2016-10-12 02:11:24 +00:00
SaveFile sav ; MysteryGift tg ; PKM temp ; string c ;
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
2016-06-20 04:22:43 +00:00
if ( input . Length = = 0x100000 )
2014-12-13 22:48:34 +00:00
{
2014-12-31 06:18:41 +00:00
if ( openXOR ( input , path ) ) // Check if we can load the save via xorpad
return ; // only if a save is loaded we abort
2015-03-11 01:44:51 +00:00
if ( BitConverter . ToUInt64 ( input , 0x10 ) ! = 0 ) // encrypted save
2017-01-08 23:27:00 +00:00
{ WinFormsUtil . Error ( "PKHeX only edits decrypted save files." + Environment . NewLine + "This save file is not decrypted." , path ) ; return ; }
2015-10-24 03:13:32 +00:00
2017-01-08 07:54:09 +00:00
DialogResult sdr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel , "Press Yes to load the sav at 0x3000" , "Press No for the one at 0x82000" ) ;
2015-10-24 03:13:32 +00:00
if ( sdr = = DialogResult . Cancel )
return ;
2016-02-09 23:37:12 +00:00
int savshift = sdr = = DialogResult . Yes ? 0 : 0x7F000 ;
2016-06-20 04:22:43 +00:00
byte [ ] psdata = input . Skip ( 0x5400 + savshift ) . Take ( SaveUtil . SIZE_G6ORAS ) . ToArray ( ) ;
2016-11-16 15:39:05 +00:00
if ( BitConverter . ToUInt32 ( psdata , SaveUtil . SIZE_G6ORAS - 0x1F0 ) = = SaveUtil . BEEF )
Array . Resize ( ref psdata , SaveUtil . SIZE_G6ORAS ) ; // set to ORAS size
else if ( BitConverter . ToUInt32 ( psdata , SaveUtil . SIZE_G6XY - 0x1F0 ) = = SaveUtil . BEEF )
Array . Resize ( ref psdata , SaveUtil . SIZE_G6XY ) ; // set to X/Y size
else if ( BitConverter . ToUInt32 ( psdata , SaveUtil . SIZE_G7SM - 0x1F0 ) = = SaveUtil . BEEF )
Array . Resize ( ref psdata , SaveUtil . SIZE_G7SM ) ; // set to S/M size
else
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Error ( "The data file is not a valid save file" , path ) ; return ; }
2014-08-15 04:27:53 +00:00
2016-11-16 15:39:05 +00:00
openSAV ( SaveUtil . getVariantSAV ( psdata ) , path ) ;
2014-08-15 04:27:53 +00:00
}
2016-06-20 04:22:43 +00:00
#endregion
#region SAV / PKM
2016-10-12 02:11:24 +00:00
else if ( ( sav = SaveUtil . getVariantSAV ( input ) ) ! = null )
2016-09-24 01:47:03 +00:00
{
2016-10-12 02:11:24 +00:00
openSAV ( sav , path ) ;
2016-09-24 01:47:03 +00:00
}
2017-04-02 14:53:46 +00:00
else if ( ( SAV3GCMemoryCard . IsMemoryCardSize ( input ) ) )
{
SAV3GCMemoryCard MC = CheckGCMemoryCard ( input , path ) ;
if ( MC = = null )
return ;
if ( ( sav = SaveUtil . getVariantSAV ( MC ) ) ! = null )
{
openSAV ( sav , path ) ;
}
else
WinFormsUtil . Error ( "Attempted to load an unsupported file type/size." ,
$"File Loaded:{Environment.NewLine}{path}" ,
$"File Size:{Environment.NewLine}{input.Length} bytes (0x{input.Length:X4})" ) ;
}
2017-02-07 06:19:10 +00:00
else if ( ( temp = PKMConverter . getPKMfromBytes ( input , prefer : ext . Length > 0 ? ( ext . Last ( ) - 0x30 ) & 7 : SAV . Generation ) ) ! = null )
2016-06-20 04:22:43 +00:00
{
2016-09-26 23:14:11 +00:00
PKM pk = PKMConverter . convertToFormat ( temp , SAV . PKMType , out c ) ;
2016-06-20 04:22:43 +00:00
if ( pk = = null )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Conversion failed." , c ) ;
2016-10-12 02:11:24 +00:00
else if ( SAV . Generation < 3 & & ( ( pk as PK1 ) ? . Japanese ? ? ( ( PK2 ) pk ) . Japanese ) ! = SAV . Japanese )
{
string a_lang = SAV . Japanese ? "an International" : "a Japanese" ;
string pk_type = pk . GetType ( ) . Name ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( $"Cannot load {a_lang} {pk_type} in {a_lang} save file." ) ;
2016-10-12 02:11:24 +00:00
}
2016-05-15 22:35:43 +00:00
else
2016-06-20 04:22:43 +00:00
populateFields ( pk ) ;
Console . WriteLine ( c ) ;
2016-05-15 22:35:43 +00:00
}
2014-08-15 04:27:53 +00:00
#endregion
2016-06-20 04:22:43 +00:00
#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
{
2016-12-16 07:17:17 +00:00
if ( SAV . getPCBin ( ) . Length = = input . Length )
{
if ( SAV . getBoxHasLockedSlot ( 0 , SAV . BoxCount - 1 ) )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Battle Box slots prevent loading of PC data." ) ;
2016-12-16 07:17:17 +00:00
else if ( SAV . setPCBin ( input ) )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "PC Binary loaded." ) ;
2016-12-16 07:17:17 +00:00
else
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Binary is not compatible with save file." , "Current SAV Generation: " + SAV . Generation ) ;
2016-12-16 07:17:17 +00:00
return ;
}
}
else if ( SAV . getBoxBin ( CB_BoxSelect . SelectedIndex ) . Length = = input . Length )
{
if ( SAV . getBoxHasLockedSlot ( CB_BoxSelect . SelectedIndex , CB_BoxSelect . SelectedIndex ) )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Battle Box slots in box prevent loading of box data." ) ;
2016-12-16 07:17:17 +00:00
else if ( SAV . setBoxBin ( input , CB_BoxSelect . SelectedIndex ) )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Box Binary loaded." ) ;
2016-12-16 07:17:17 +00:00
else
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Binary is not compatible with save file." , "Current SAV Generation: " + SAV . Generation ) ;
2016-12-16 07:17:17 +00:00
return ;
}
}
2014-12-13 22:48:34 +00:00
else
2015-09-18 03:18:22 +00:00
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Binary is not compatible with save file." , "Current SAV Generation: " + SAV . Generation ) ;
2016-06-20 04:22:43 +00:00
return ;
2015-10-24 03:13:32 +00:00
}
2015-01-27 06:05:04 +00:00
setPKXBoxes ( ) ;
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2015-09-18 03:18:22 +00:00
}
2015-01-24 18:45:32 +00:00
#endregion
2015-02-24 07:52:32 +00:00
#region Battle Video
2016-11-10 16:14:54 +00:00
else if ( BattleVideo . getIsValid ( input ) )
2015-02-24 07:52:32 +00:00
{
2016-11-10 16:14:54 +00:00
BattleVideo b = BattleVideo . getVariantBattleVideo ( input ) ;
if ( SAV . Generation ! = b . Generation )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( $"Cannot load a Gen{b.Generation} Battle Video to a different generation save file." ) ; return ; }
2016-04-15 00:10:06 +00:00
2017-01-08 07:54:09 +00:00
if ( WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , $"Load Battle Video Pokémon data to {CB_BoxSelect.Text}?" , "The box will be overwritten." ) ! = DialogResult . Yes )
2016-06-20 04:22:43 +00:00
return ;
2016-04-15 00:10:06 +00:00
2016-06-20 04:22:43 +00:00
bool? noSetb = getPKMSetOverride ( ) ;
2016-11-10 16:14:54 +00:00
PKM [ ] data = b . BattlePKMs ;
2016-06-20 04:22:43 +00:00
int offset = SAV . getBoxOffset ( CB_BoxSelect . SelectedIndex ) ;
2016-12-16 07:17:17 +00:00
int slotSkipped = 0 ;
2015-02-24 07:52:32 +00:00
for ( int i = 0 ; i < 24 ; i + + )
2016-12-16 07:17:17 +00:00
{
if ( SAV . getIsSlotLocked ( CB_BoxSelect . SelectedIndex , i ) )
{ slotSkipped + + ; continue ; }
2016-10-16 04:28:14 +00:00
SAV . setStoredSlot ( data [ i ] , offset + i * SAV . SIZE_STORED , noSetb ) ;
2016-12-16 07:17:17 +00:00
}
if ( slotSkipped > 0 )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( $"Skipped {slotSkipped} locked slot{(slotSkipped > 1 ? " s " : " ")}." ) ;
2016-10-16 04:28:14 +00:00
2015-02-24 07:52:32 +00:00
setPKXBoxes ( ) ;
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2015-02-24 07:52:32 +00:00
}
#endregion
2016-06-20 04:22:43 +00:00
#region Mystery Gift ( Templates )
else if ( ( tg = MysteryGift . getMysteryGift ( input , ext ) ) ! = null )
2015-12-27 00:05:26 +00:00
{
2016-06-20 04:22:43 +00:00
if ( ! tg . IsPokémon )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Mystery Gift is not a Pokémon." , path ) ; return ; }
2016-10-12 02:11:24 +00:00
2016-06-20 04:22:43 +00:00
temp = tg . convertToPKM ( SAV ) ;
2016-09-26 23:14:11 +00:00
PKM pk = PKMConverter . convertToFormat ( temp , SAV . PKMType , out c ) ;
2016-10-12 02:11:24 +00:00
2016-06-20 04:22:43 +00:00
if ( pk = = null )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Conversion failed." , c ) ;
2016-06-20 04:22:43 +00:00
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
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( "Attempted to load an unsupported file type/size." ,
2016-01-17 21:27:24 +00:00
$"File Loaded:{Environment.NewLine}{path}" ,
2016-12-08 06:57:08 +00:00
$"File Size:{Environment.NewLine}{input.Length} bytes (0x{input.Length:X4})" ) ;
2014-12-13 22:48:34 +00:00
}
2014-12-31 06:18:41 +00:00
private bool openXOR ( byte [ ] input , string path )
{
2017-02-09 08:44:38 +00:00
// try to get a save file via xorpad in same folder
string [ ] pads = Directory . GetFiles ( path ) ;
var s = SaveUtil . getSAVfromXORpads ( input , pads ) ;
2014-12-31 06:18:41 +00:00
2017-02-09 08:44:38 +00:00
if ( s = = null ) // failed to find xorpad in path folder
2015-03-11 01:44:51 +00:00
{
2017-02-09 08:44:38 +00:00
// try again
pads = Directory . GetFiles ( WorkingDirectory ) ;
s = SaveUtil . getSAVfromXORpads ( input , pads ) ;
2014-12-31 06:18:41 +00:00
}
2017-02-09 08:44:38 +00:00
if ( s = = null )
return false ; // failed
openSAV ( s , s . FileName ) ;
return true ;
2014-12-31 06:18:41 +00:00
}
2017-04-02 20:42:42 +00:00
private static GameVersion SelectMemoryCardSaveGame ( SAV3GCMemoryCard MC )
2017-04-02 14:53:46 +00:00
{
if ( MC . SaveGameCount = = 1 )
return MC . SelectedGameVersion ;
2017-04-02 20:42:42 +00:00
var games = new List < ComboItem > ( ) ;
if ( MC . HasCOLO ) games . Add ( new ComboItem { Text = "Colosseum" , Value = ( int ) GameVersion . COLO } ) ;
if ( MC . HasXD ) games . Add ( new ComboItem { Text = "XD" , Value = ( int ) GameVersion . XD } ) ;
if ( MC . HasRSBOX ) games . Add ( new ComboItem { Text = "RS Box" , Value = ( int ) GameVersion . RSBOX } ) ;
2017-04-02 14:53:46 +00:00
2017-04-02 20:42:42 +00:00
WinFormsUtil . Alert ( "Multiple games detected" , "Select a game to edit." ) ;
var dialog = new SAV_GameSelect ( games . ToArray ( ) ) ;
dialog . ShowDialog ( ) ;
return dialog . Result ;
}
private static SAV3GCMemoryCard CheckGCMemoryCard ( byte [ ] Data , string path )
2017-04-02 14:53:46 +00:00
{
SAV3GCMemoryCard MC = new SAV3GCMemoryCard ( ) ;
GCMemoryCardState MCState = MC . LoadMemoryCardFile ( Data ) ;
2017-04-02 20:42:42 +00:00
switch ( MCState )
2017-04-02 14:53:46 +00:00
{
2017-04-02 20:42:42 +00:00
default : { WinFormsUtil . Error ( "Invalid or corrupted GC Memory Card. Aborting." , path ) ; return null ; }
2017-04-02 14:53:46 +00:00
case GCMemoryCardState . NoPkmSaveGame : { WinFormsUtil . Error ( "GC Memory Card without any Pokémon save file. Aborting." , path ) ; return null ; }
2017-04-02 20:42:42 +00:00
case GCMemoryCardState . DuplicateCOLO :
case GCMemoryCardState . DuplicateXD :
case GCMemoryCardState . DuplicateRSBOX : { WinFormsUtil . Error ( "GC Memory Card with duplicated game save files. Aborting." , path ) ; return null ; }
2017-04-02 14:53:46 +00:00
case GCMemoryCardState . MultipleSaveGame :
{
GameVersion Game = SelectMemoryCardSaveGame ( MC ) ;
2017-04-02 20:42:42 +00:00
if ( Game = = GameVersion . Invalid ) //Cancel
2017-04-02 14:53:46 +00:00
return null ;
MC . SelectSaveGame ( Game ) ;
break ;
}
2017-04-02 20:42:42 +00:00
case GCMemoryCardState . SaveGameCOLO : { MC . SelectSaveGame ( GameVersion . COLO ) ; break ; }
case GCMemoryCardState . SaveGameXD : { MC . SelectSaveGame ( GameVersion . XD ) ; break ; }
case GCMemoryCardState . SaveGameRSBOX : { MC . SelectSaveGame ( GameVersion . RSBOX ) ; break ; }
2017-04-02 14:53:46 +00:00
}
return MC ;
}
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
private void StoreLegalSaveGameData ( SaveFile sav )
{
Legal . SavegameJapanese = sav . Japanese ;
Legal . EReaderBerryIsEnigma = sav . eBerryIsEnigma ;
Legal . EReaderBerryName = sav . eBerryName ;
Legal . Savegame_Gender = sav . Gender ;
Legal . Savegame_TID = sav . TID ;
Legal . Savegame_SID = sav . SID ;
Legal . Savegame_OT = sav . OT ;
Legal . Savegame_Version = sav . Version ;
}
2016-10-12 02:11:24 +00:00
private void openSAV ( SaveFile sav , string path )
2014-12-13 22:48:34 +00:00
{
2016-06-28 06:03:57 +00:00
if ( sav = = null | | sav . Version = = GameVersion . Invalid )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Error ( "Invalid save file loaded. Aborting." , path ) ; return ; }
2016-10-12 02:11:24 +00:00
2016-11-12 15:38:56 +00:00
if ( ! string . IsNullOrEmpty ( path ) ) // If path is null, this is the default save
2016-11-12 15:30:51 +00:00
{
2016-11-12 15:38:56 +00:00
if ( sav . RequiresMemeCrypto & & ! MemeCrypto . CanUseMemeCrypto ( ) )
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( "Your platform does not support the required cryptography components." , "In order to be able to save your changes, you must either upgrade to a newer version of Windows or disable FIPS compliance mode." ) ;
2016-11-12 15:38:56 +00:00
// Don't abort loading; user can still view save and fix checksum on another platform.
}
2017-01-26 04:11:53 +00:00
}
2016-10-12 02:11:24 +00:00
// Finish setting up the save file.
2017-03-12 23:36:23 +00:00
if ( sav . Generation = = 1 )
{
// Ask the user if it is a VC save file or if it is from a physical cartridge.
// Necessary for legality checking possibilities that are only obtainable on GSC (non VC) or event distributions.
var drVC = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel , $"{sav.Version} Save File detected. Is this a Virtual Console Save File?" ,
"Yes: Virtual Console" + Environment . NewLine + "No: Physical Cartridge" ) ;
if ( drVC = = DialogResult . Cancel )
return ;
Legal . AllowGBCartEra = drVC = = DialogResult . No ; // physical cart selected
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
if ( Legal . AllowGBCartEra & & sav . Generation = = 1 )
{
2017-04-27 05:05:32 +00:00
var drTradeback = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel , $"Generation {SAV.Generation} Save File detected. Allow tradebacks from Generation 2 for legality purposes?" ,
"Yes: Allow Generation 2 tradeback learnsets" + Environment . NewLine + "No: Don't allow Generation 2 tradeback learnsets" ) ;
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
Legal . AllowGen1Tradeback = drTradeback = = DialogResult . Yes ;
}
else
Legal . AllowGen1Tradeback = false ;
2017-03-12 23:36:23 +00:00
}
2017-03-18 05:27:59 +00:00
else
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
Legal . AllowGBCartEra = Legal . AllowGen1Tradeback = sav . Generation = = 2 ;
2017-03-18 05:27:59 +00:00
if ( sav . Generation = = 3 & & ( sav . IndeterminateGame | | ModifierKeys = = Keys . Control ) )
2016-07-15 03:22:24 +00:00
{
2017-04-27 05:05:32 +00:00
WinFormsUtil . Alert ( $"Generation {SAV.Generation} Save File detected." , "Select version." ) ;
2017-04-10 23:28:44 +00:00
var g = new [ ] { GameVersion . R , GameVersion . S , GameVersion . E , GameVersion . FR , GameVersion . LG } ;
var games = g . Select ( z = > GameInfo . VersionDataSource . First ( v = > v . Value = = ( int ) z ) ) ;
2017-04-02 20:42:42 +00:00
var dialog = new SAV_GameSelect ( games ) ;
dialog . ShowDialog ( ) ;
switch ( dialog . Result ) // Reset save file info
{
case GameVersion . R :
case GameVersion . S : sav = new SAV3 ( sav . BAK , GameVersion . RS ) ; break ;
case GameVersion . E : sav = new SAV3 ( sav . BAK , GameVersion . E ) ; break ;
case GameVersion . FR :
case GameVersion . LG : sav = new SAV3 ( sav . BAK , GameVersion . FRLG ) ; break ;
2016-10-12 02:11:24 +00:00
default : return ;
2016-07-29 05:08:23 +00:00
}
2017-04-02 20:42:42 +00:00
if ( sav . Version = = GameVersion . FRLG )
sav . Personal = dialog . Result = = GameVersion . FR ? PersonalTable . FR : PersonalTable . LG ;
2016-10-12 02:11:24 +00:00
}
2017-04-02 20:42:42 +00:00
else if ( sav . IndeterminateSubVersion & & sav . Version = = GameVersion . FRLG )
{
2017-04-10 23:28:44 +00:00
string fr = GameInfo . VersionDataSource . First ( r = > r . Value = = ( int ) GameVersion . FR ) . Text ;
string lg = GameInfo . VersionDataSource . First ( l = > l . Value = = ( int ) GameVersion . LG ) . Text ;
2017-04-27 05:05:32 +00:00
const string dual = "{0}/{1} Save File Detected." ;
2017-04-10 23:28:44 +00:00
WinFormsUtil . Alert ( string . Format ( dual , fr , lg ) , "Select version." ) ;
var g = new [ ] { GameVersion . FR , GameVersion . LG } ;
var games = g . Select ( z = > GameInfo . VersionDataSource . First ( v = > v . Value = = ( int ) z ) ) ;
var dialog = new SAV_GameSelect ( games ) ;
2017-04-02 20:42:42 +00:00
dialog . ShowDialog ( ) ;
2017-04-10 23:28:44 +00:00
2017-04-02 20:42:42 +00:00
sav . Personal = dialog . Result = = GameVersion . FR ? PersonalTable . FR : PersonalTable . LG ;
}
2016-10-12 02:11:24 +00:00
if ( sav . IndeterminateLanguage )
{
// Japanese Save files are different. Get isJapanese
2017-01-08 07:54:09 +00:00
var drJP = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel , $"{sav.Version} Save File detected. Select language..." ,
2016-10-12 02:11:24 +00:00
"Yes: International" + Environment . NewLine + "No: Japanese" ) ;
2016-07-28 01:59:10 +00:00
if ( drJP = = DialogResult . Cancel )
2016-07-15 03:22:24 +00:00
return ;
2016-07-28 01:59:10 +00:00
2016-10-12 02:11:24 +00:00
sav . Japanese = drJP = = DialogResult . No ;
}
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
StoreLegalSaveGameData ( sav ) ;
2017-03-22 06:25:13 +00:00
loadingSAV = true ;
2016-10-12 02:11:24 +00:00
2016-09-06 06:13:46 +00:00
// clean fields
2017-02-14 04:42:39 +00:00
bool WindowToggleRequired = SAV . Generation < 3 & & sav . Generation > = 3 ; // version combobox refresh hack
bool WindowTranslationRequired = false ;
2016-09-26 23:14:11 +00:00
PKM pk = preparePKM ( ) ;
2016-09-28 05:43:03 +00:00
populateFields ( SAV . BlankPKM ) ;
2016-06-20 04:22:43 +00:00
SAV = sav ;
2016-01-03 06:31:04 +00:00
2017-04-10 23:28:44 +00:00
string title = $"PKH{(HaX ? " a " : " e ")}X ({Resources.ProgramVersion}) - " + $"{SAV.GetType().Name}: " ;
2016-08-11 04:10:21 +00:00
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 ) ;
2017-01-04 05:05:23 +00:00
Text = title + $"{Path.GetFileNameWithoutExtension(Util.CleanFileName(SAV.BAKName))}" ; // more descriptive
2016-08-11 04:10:21 +00:00
// 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" ;
2017-01-04 05:05:23 +00:00
Text = title + $"{SAV.FileName} [{SAV.OT} ({SAV.Version})]" ;
2016-08-11 04:10:21 +00:00
GB_SAVtools . Visible = false ;
}
2016-01-28 04:24:32 +00:00
Menu_ExportSAV . Enabled = B_VerifyCHK . Enabled = SAV . Exportable ;
2016-04-19 01:21:50 +00:00
2016-08-26 01:50:51 +00:00
// Close subforms that are save dependent
2017-04-09 21:06:50 +00:00
Type [ ] f = { typeof ( SAV_BoxViewer ) } ;
2016-08-26 01:50:51 +00:00
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
2016-06-20 04:22:43 +00:00
if ( SAV . HasBox )
2015-12-30 06:03:27 +00:00
{
2016-08-11 04:10:21 +00:00
int startBox = path = = null ? 0 : SAV . CurrentBox ; // FF if BattleBox
2016-06-20 04:22:43 +00:00
if ( startBox > SAV . BoxCount - 1 ) { tabBoxMulti . SelectedIndex = 1 ; CB_BoxSelect . SelectedIndex = 0 ; }
2015-12-30 06:03:27 +00:00
else { tabBoxMulti . SelectedIndex = 0 ; CB_BoxSelect . SelectedIndex = startBox ; }
}
2016-06-20 04:22:43 +00:00
setPKXBoxes ( ) ; // Reload all of the PKX Windows
2015-12-17 03:33:58 +00:00
2015-12-30 06:03:27 +00:00
// Hide content if not present in game.
2016-06-20 04:22:43 +00:00
GB_SUBE . Visible = SAV . HasSUBE ;
PB_Locked . Visible = SAV . HasBattleBox & & SAV . BattleBoxLocked ;
2016-09-10 20:40:03 +00:00
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 ) ;
2016-09-12 01:57:12 +00:00
WindowTranslationRequired = true ;
2016-09-10 20:40:03 +00:00
}
2016-06-20 04:22:43 +00:00
Menu_LoadBoxes . Enabled = Menu_DumpBoxes . Enabled = Menu_Report . Enabled = Menu_Modify . Enabled = B_SaveBoxBin . Enabled = SAV . HasBox ;
2016-09-19 05:47:31 +00:00
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 ;
}
2016-09-12 01:57:12 +00:00
if ( ! SAV . HasDaycare & & tabBoxMulti . TabPages . Contains ( Tab_Other ) )
tabBoxMulti . TabPages . Remove ( Tab_Other ) ;
else if ( SAV . HasDaycare & & ! tabBoxMulti . TabPages . Contains ( Tab_Other ) )
{
2016-09-19 05:47:31 +00:00
int index = PartyTab ;
if ( index < 0 )
index = BoxTab ;
if ( index < 0 )
index = - 1 ;
tabBoxMulti . TabPages . Insert ( index + 1 , Tab_Other ) ;
2016-09-12 01:57:12 +00:00
WindowTranslationRequired = true ;
}
2016-08-20 06:36:13 +00:00
if ( path ! = null ) // Actual save file
2016-08-11 04:10:21 +00:00
{
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 ;
2016-09-21 15:34:06 +00:00
B_OpenSecretBase . Enabled = SAV . HasSecretBase ;
B_OpenPokepuffs . Enabled = SAV . HasPuff ;
2016-11-15 05:40:31 +00:00
B_OpenPokeBeans . Enabled = SAV . Generation = = 7 ;
2016-12-06 03:19:19 +00:00
B_OpenZygardeCells . Enabled = SAV . Generation = = 7 ;
2016-09-21 15:34:06 +00:00
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 ;
2017-04-05 01:58:32 +00:00
B_OpenFriendSafari . Enabled = SAV . XY ;
2016-09-21 15:34:06 +00:00
B_OpenPokeblocks . Enabled = SAV . HasPokeBlock ;
2016-11-10 04:04:02 +00:00
B_JPEG . Visible = SAV . HasJPEG ;
2016-09-21 15:34:06 +00:00
B_OpenEventFlags . Enabled = SAV . HasEvents ;
B_OpenLinkInfo . Enabled = SAV . HasLink ;
B_CGearSkin . Enabled = SAV . Generation = = 5 ;
2016-09-19 05:47:31 +00:00
2017-01-03 06:16:15 +00:00
B_OpenTrainerInfo . Enabled = B_OpenItemPouch . Enabled = SAV . HasParty ; // Box RS
2017-04-22 12:39:53 +00:00
B_OpenMiscEditor . Enabled = SAV is SAV3 | | SAV . DP | | SAV . HGSS ;
2017-04-07 00:39:37 +00:00
B_OpenHoneyTreeEditor . Enabled = SAV . DP | | SAV . Pt ;
2017-04-14 02:11:01 +00:00
B_OpenRTCEditor . Enabled = SAV . RS | | SAV . E ;
2016-08-11 04:10:21 +00:00
}
2017-01-11 04:01:33 +00:00
GB_SAVtools . Visible = ( path ! = null ) & & FLP_SAVtools . Controls . Cast < Control > ( ) . Any ( c = > c . Enabled ) ;
2016-09-21 15:34:06 +00:00
foreach ( Control c in FLP_SAVtools . Controls . Cast < Control > ( ) )
c . Visible = c . Enabled ;
2016-09-19 05:47:31 +00:00
2016-06-20 04:22:43 +00:00
// Generational Interface
2016-06-21 04:11:48 +00:00
Tip1 . RemoveAll ( ) ; Tip2 . RemoveAll ( ) ; Tip3 . RemoveAll ( ) ; // TSV/PSV
2016-06-26 21:23:41 +00:00
2016-09-05 21:26:21 +00:00
FLP_Country . Visible = FLP_SubRegion . Visible = FLP_3DSRegion . Visible = SAV . Generation > = 6 ;
2016-06-26 21:23:41 +00:00
Label_EncryptionConstant . Visible = BTN_RerollEC . Visible = TB_EC . Visible = SAV . Generation > = 6 ;
2016-07-17 00:19:26 +00:00
GB_nOT . Visible = GB_RelearnMoves . Visible = BTN_Medals . Visible = BTN_History . Visible = SAV . Generation > = 6 ;
2016-06-26 21:23:41 +00:00
PB_Legal . Visible = PB_WarnMove1 . Visible = PB_WarnMove2 . Visible = PB_WarnMove3 . Visible = PB_WarnMove4 . Visible = SAV . Generation > = 6 ;
2016-10-27 05:06:03 +00:00
PB_MarkPentagon . Visible = SAV . Generation > = 6 ;
2017-01-24 15:12:14 +00:00
PB_MarkAlola . Visible = PB_MarkVC . Visible = PB_MarkHorohoro . Visible = SAV . Generation > = 7 ;
2016-12-07 22:04:44 +00:00
TB_Secure1 . Visible = TB_Secure2 . Visible = L_Secure1 . Visible = L_Secure2 . Visible = SAV . Exportable & & SAV . Generation > = 6 ;
TB_GameSync . Visible = L_GameSync . Visible = SAV . Exportable & & SAV . Generation > = 6 ;
2016-06-26 21:23:41 +00:00
2016-09-05 21:26:21 +00:00
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 ;
2016-06-26 21:23:41 +00:00
2016-07-15 03:15:05 +00:00
DEV_Ability . Enabled = DEV_Ability . Visible = SAV . Generation > 3 & & HaX ;
CB_Ability . Visible = ! DEV_Ability . Enabled & & SAV . Generation > = 3 ;
2016-09-05 21:26:21 +00:00
FLP_Nature . Visible = SAV . Generation > = 3 ;
FLP_Ability . Visible = SAV . Generation > = 3 ;
FLP_Language . Visible = SAV . Generation > = 3 ;
2016-09-06 23:46:00 +00:00
GB_ExtraBytes . Visible = GB_ExtraBytes . Enabled = SAV . Generation > = 3 ;
2016-09-05 21:26:21 +00:00
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 ;
2016-06-26 21:23:41 +00:00
2016-09-05 21:26:21 +00:00
FLP_FriendshipForm . Visible = SAV . Generation > = 2 ;
FLP_HeldItem . Visible = SAV . Generation > = 2 ;
CHK_IsEgg . Visible = Label_Gender . Visible = SAV . Generation > = 2 ;
2016-09-07 16:10:38 +00:00
FLP_PKRS . Visible = FLP_EggPKRSRight . Visible = SAV . Generation > = 2 ;
Label_OTGender . Visible = SAV . Generation > = 2 ;
2016-08-29 05:21:55 +00:00
2016-09-26 23:14:11 +00:00
if ( SAV . Version = = GameVersion . BATREV )
{
L_SaveSlot . Visible = CB_SaveSlot . Visible = true ;
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 ;
2016-10-01 23:52:29 +00:00
FLP_Purification . Visible = FLP_ShadowID . Visible = SAV . Version = = GameVersion . COLO | | SAV . Version = = GameVersion . XD ;
NUD_ShadowID . Maximum = SAV . MaxShadowID ;
2016-09-26 23:14:11 +00:00
2016-09-05 22:57:28 +00:00
// HaX override, needs to be after DEV_Ability enabled assignment.
TB_AbilityNumber . Visible = SAV . Generation > = 6 & & DEV_Ability . Enabled ;
2016-09-05 21:26:21 +00:00
// 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
2016-09-05 21:26:21 +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
2016-09-05 21:26:21 +00:00
PAN_Contest . Visible = SAV . Generation > = 3 ;
2016-08-29 05:21:55 +00:00
2016-09-05 21:26:21 +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 )
2016-08-28 10:18:22 +00:00
{
2016-09-05 21:26:21 +00:00
FLP_SpD . Visible = false ;
Label_SPA . Visible = false ;
Label_SPC . Visible = true ;
2016-09-11 00:14:25 +00:00
TB_HPIV . Enabled = false ;
2016-08-31 05:58:39 +00:00
MaskedTextBox [ ] evControls = { TB_SPAEV , TB_HPEV , TB_ATKEV , TB_DEFEV , TB_SPEEV , TB_SPDEV } ;
foreach ( var ctrl in evControls )
2016-08-28 10:18:22 +00:00
{
ctrl . Mask = "00000" ;
2016-09-05 21:26:21 +00:00
ctrl . Size = Stat_HP . Size ;
2016-08-28 10:18:22 +00:00
}
}
2016-09-04 06:45:10 +00:00
else if ( sav . Generation = = 2 )
{
2016-09-05 21:26:21 +00:00
FLP_SpD . Visible = true ;
Label_SPA . Visible = true ;
Label_SPC . Visible = false ;
2016-09-11 00:14:25 +00:00
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" ;
2016-09-05 21:26:21 +00:00
ctrl . Size = Stat_HP . Size ;
2016-09-04 06:45:10 +00:00
}
}
2016-08-28 10:18:22 +00:00
else
{
2016-09-05 21:26:21 +00:00
FLP_SpD . Visible = true ;
Label_SPA . Visible = true ;
Label_SPC . Visible = false ;
2016-09-11 00:14:25 +00:00
TB_SPDEV . Enabled = TB_SPDIV . Enabled = true ;
TB_HPIV . Enabled = true ;
2016-08-31 05:58:39 +00:00
MaskedTextBox [ ] evControls = { TB_SPAEV , TB_HPEV , TB_ATKEV , TB_DEFEV , TB_SPEEV , TB_SPDEV } ;
foreach ( var ctrl in evControls )
2016-08-28 10:18:22 +00:00
{
ctrl . Mask = "000" ;
2016-09-05 21:26:21 +00:00
ctrl . Size = TB_ExtraByte . Size ;
2016-08-28 10:18:22 +00:00
}
}
2016-07-17 00:19:26 +00:00
// Recenter PKM SubEditors
2016-09-06 06:13:46 +00:00
FLP_PKMEditors . Location = new Point ( ( Tab_OTMisc . Width - FLP_PKMEditors . Width ) / 2 , FLP_PKMEditors . Location . Y ) ;
2016-07-17 00:19:26 +00:00
2016-11-16 15:46:54 +00:00
bool init = fieldsInitialized ;
fieldsInitialized = fieldsLoaded = false ;
2016-06-20 04:22:43 +00:00
switch ( SAV . Generation )
{
case 6 :
2016-12-10 20:27:37 +00:00
TB_GameSync . Enabled = SAV . GameSyncID ! = null ;
TB_GameSync . MaxLength = SAV . GameSyncIDSize ;
TB_GameSync . Text = ( SAV . GameSyncID ? ? 0. ToString ( ) ) . PadLeft ( SAV . GameSyncIDSize , '0' ) ;
2016-10-27 05:06:03 +00:00
TB_Secure1 . Text = SAV . Secure1 ? . ToString ( "X16" ) ;
TB_Secure2 . Text = SAV . Secure2 ? . ToString ( "X16" ) ;
2016-06-20 04:22:43 +00:00
break ;
2016-10-20 01:19:01 +00:00
case 7 :
2016-12-10 20:27:37 +00:00
TB_GameSync . Enabled = SAV . GameSyncID ! = null ;
TB_GameSync . MaxLength = SAV . GameSyncIDSize ;
TB_GameSync . Text = ( SAV . GameSyncID ? ? 0. ToString ( ) ) . PadLeft ( SAV . GameSyncIDSize , '0' ) ;
2016-10-27 05:06:03 +00:00
TB_Secure1 . Text = SAV . Secure1 ? . ToString ( "X16" ) ;
TB_Secure2 . Text = SAV . Secure2 ? . ToString ( "X16" ) ;
2016-10-20 01:19:01 +00:00
break ;
2016-06-20 04:22:43 +00:00
}
2016-09-28 05:43:03 +00:00
pkm = pkm . GetType ( ) ! = SAV . PKMType ? SAV . BlankPKM : pk ;
2016-10-04 05:24:03 +00:00
if ( pkm . Format < 3 )
pkm = SAV . BlankPKM ;
2016-06-21 01:58:06 +00:00
populateFilteredDataSources ( ) ;
2016-09-06 02:44:15 +00:00
populateFields ( pkm ) ;
2016-07-03 22:05:15 +00:00
fieldsInitialized | = init ;
2016-06-20 04:22:43 +00:00
// SAV Specific Limits
TB_OT . MaxLength = SAV . OTLength ;
TB_OTt2 . MaxLength = SAV . OTLength ;
TB_Nickname . MaxLength = SAV . NickLength ;
2016-09-06 06:13:46 +00:00
// 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 ) ;
2016-09-12 01:57:12 +00:00
WindowTranslationRequired = true ;
2016-09-06 06:13:46 +00:00
}
2016-06-20 04:22:43 +00:00
// 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 ;
2017-01-15 00:43:16 +00:00
// Setup PKM Preparation/Extra Bytes
setPKMFormatMode ( SAV . Generation , SAV . Version ) ;
2015-12-30 06:03:27 +00:00
2016-09-11 22:14:42 +00:00
// pk2 save files do not have an Origin Game stored. Prompt the met location list to update.
if ( SAV . Generation = = 2 )
updateOriginGame ( null , null ) ;
2016-10-29 22:41:55 +00:00
// Refresh PK* conversion info
2017-01-26 06:51:52 +00:00
PKMConverter . updateConfig ( SAV . SubRegion , SAV . Country , SAV . ConsoleRegion , SAV . OT , SAV . Gender , SAV . Language ) ;
2016-02-12 05:41:31 +00:00
2016-09-12 01:57:12 +00:00
if ( WindowTranslationRequired ) // force update -- re-added controls may be untranslated
2017-02-14 04:42:39 +00:00
{
// Keep window title
title = Text ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . TranslateInterface ( this , curlanguage ) ;
2017-02-14 04:42:39 +00:00
Text = title ;
}
if ( WindowToggleRequired ) // Version combobox selectedvalue needs a little help, only updates once it is visible
{
tabMain . SelectedTab = Tab_Met ; // parent tab of CB_GameOrigin
tabMain . SelectedTab = Tab_Main ; // first tab
}
2016-10-04 02:27:48 +00:00
// No changes made yet
UndoStack . Clear ( ) ; Menu_Undo . Enabled = false ;
RedoStack . Clear ( ) ; Menu_Redo . Enabled = false ;
2016-09-12 01:57:12 +00:00
2017-01-26 04:11:53 +00:00
if ( ! string . IsNullOrWhiteSpace ( path ) ) // Actual Save
{
// Check location write protection
2017-01-28 18:50:36 +00:00
bool locked = true ;
2017-02-05 07:11:48 +00:00
try { locked = File . GetAttributes ( path ) . HasFlag ( FileAttributes . ReadOnly ) ; }
2017-01-28 18:50:36 +00:00
catch { }
if ( locked )
2017-02-05 07:11:48 +00:00
WinFormsUtil . Alert ( "File's location is write protected:\n" + path ,
2017-01-26 04:11:53 +00:00
"If the path is a removable disk (SD card), please ensure the write protection switch is not set." ) ;
}
2017-01-29 08:02:32 +00:00
TemplateFields ( ) ;
2017-03-22 06:25:13 +00:00
loadingSAV = false ;
2017-04-18 06:36:46 +00:00
SAV . Edited = false ;
2017-01-29 08:02:32 +00:00
2016-06-20 04:22:43 +00:00
// Indicate audibly the save is loaded
SystemSounds . Beep . Play ( ) ;
2014-06-28 21:22:05 +00:00
}
2017-03-19 23:19:59 +00:00
2017-04-19 10:15:50 +00:00
private static void refreshMGDB ( )
2017-03-19 23:19:59 +00:00
{
2017-04-19 10:15:50 +00:00
var g4 = getPCDDB ( Resources . pcd ) ;
var g5 = getPGFDB ( Resources . pgf ) ;
var g6 = getWC6DB ( Resources . wc6 , Resources . wc6full ) ;
var g7 = getWC7DB ( Resources . wc7 , Resources . wc7full ) ;
2017-04-20 01:47:42 +00:00
if ( Directory . Exists ( MGDatabasePath ) )
2017-04-19 10:15:50 +00:00
foreach ( var file in Directory . GetFiles ( MGDatabasePath , "*" , SearchOption . AllDirectories ) )
{
var fi = new FileInfo ( file ) ;
if ( ! MysteryGift . getIsMysteryGift ( fi . Length ) )
continue ;
var gift = MysteryGift . getMysteryGift ( File . ReadAllBytes ( file ) , fi . Extension ) ;
switch ( gift ? . Format )
{
case 4 : g4 . Add ( gift ) ; continue ;
case 5 : g5 . Add ( gift ) ; continue ;
case 6 : g6 . Add ( gift ) ; continue ;
case 7 : g7 . Add ( gift ) ; continue ;
}
}
Legal . MGDB_G4 = g4 . ToArray ( ) ;
Legal . MGDB_G5 = g5 . ToArray ( ) ;
Legal . MGDB_G6 = g6 . ToArray ( ) ;
Legal . MGDB_G7 = g7 . ToArray ( ) ;
}
private static HashSet < MysteryGift > getPCDDB ( byte [ ] bin )
{
var db = new HashSet < MysteryGift > ( ) ;
2017-03-19 23:19:59 +00:00
for ( int i = 0 ; i < bin . Length ; i + = PCD . Size )
{
byte [ ] data = new byte [ PCD . Size ] ;
Buffer . BlockCopy ( bin , i , data , 0 , PCD . Size ) ;
db . Add ( new PCD ( data ) ) ;
}
2017-04-19 10:15:50 +00:00
return db ;
2017-03-19 23:19:59 +00:00
}
2017-04-19 10:15:50 +00:00
private static HashSet < MysteryGift > getPGFDB ( byte [ ] bin )
2017-03-19 23:19:59 +00:00
{
2017-04-19 10:15:50 +00:00
var db = new HashSet < MysteryGift > ( ) ;
2017-03-19 23:19:59 +00:00
for ( int i = 0 ; i < bin . Length ; i + = PGF . Size )
{
byte [ ] data = new byte [ PGF . Size ] ;
Buffer . BlockCopy ( bin , i , data , 0 , PGF . Size ) ;
db . Add ( new PGF ( data ) ) ;
}
2017-04-19 10:15:50 +00:00
return db ;
2017-03-19 23:19:59 +00:00
}
2017-04-19 10:15:50 +00:00
private static HashSet < MysteryGift > getWC6DB ( byte [ ] wc6bin , byte [ ] wc6full )
2016-02-29 01:05:38 +00:00
{
2017-04-19 10:15:50 +00:00
var db = new HashSet < MysteryGift > ( ) ;
2016-02-29 01:05:38 +00:00
for ( int i = 0 ; i < wc6bin . Length ; i + = WC6 . Size )
2016-08-13 01:29:31 +00:00
{
byte [ ] data = new byte [ WC6 . Size ] ;
2017-04-19 10:15:50 +00:00
Buffer . BlockCopy ( wc6bin , i , data , 0 , WC6 . Size ) ;
db . Add ( new WC6 ( data ) ) ;
2016-08-13 01:29:31 +00:00
}
2016-04-30 06:24:23 +00:00
for ( int i = 0 ; i < wc6full . Length ; i + = WC6 . SizeFull )
2016-08-13 01:29:31 +00:00
{
byte [ ] data = new byte [ WC6 . SizeFull ] ;
2017-04-19 10:15:50 +00:00
Buffer . BlockCopy ( wc6full , i , data , 0 , WC6 . SizeFull ) ;
db . Add ( new WC6 ( data ) ) ;
2016-08-13 01:29:31 +00:00
}
2017-04-19 10:15:50 +00:00
return db ;
2016-02-29 01:05:38 +00:00
}
2017-04-19 10:15:50 +00:00
private static HashSet < MysteryGift > getWC7DB ( byte [ ] wc7bin , byte [ ] wc7full )
2016-11-13 21:11:53 +00:00
{
2017-04-19 10:15:50 +00:00
var db = new HashSet < MysteryGift > ( ) ;
2016-11-13 21:11:53 +00:00
for ( int i = 0 ; i < wc7bin . Length ; i + = WC7 . Size )
{
byte [ ] data = new byte [ WC7 . Size ] ;
2017-04-19 10:15:50 +00:00
Buffer . BlockCopy ( wc7bin , i , data , 0 , WC7 . Size ) ;
db . Add ( new WC7 ( data ) ) ;
2016-11-13 21:11:53 +00:00
}
for ( int i = 0 ; i < wc7full . Length ; i + = WC7 . SizeFull )
{
byte [ ] data = new byte [ WC7 . SizeFull ] ;
2017-04-19 10:15:50 +00:00
Buffer . BlockCopy ( wc7full , i , data , 0 , WC7 . SizeFull ) ;
db . Add ( new WC7 ( data ) ) ;
2016-11-13 21:11:53 +00:00
}
2017-04-19 10:15:50 +00:00
return db ;
2016-11-13 21:11:53 +00:00
}
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
{
2017-03-24 18:18:14 +00:00
if ( CB_MainLanguage . SelectedIndex < 8 )
curlanguage = GameInfo . lang_val [ CB_MainLanguage . SelectedIndex ] ;
// Set the culture (makes it easy to pass language to other forms)
Properties . Settings . Default . Language = curlanguage ;
Thread . CurrentThread . CurrentCulture = new CultureInfo ( curlanguage . Substring ( 0 , 2 ) ) ;
Thread . CurrentThread . CurrentUICulture = Thread . CurrentThread . CurrentCulture ;
2016-06-20 04:22:43 +00:00
PKM pk = SAV . getPKM ( ( fieldsInitialized ? preparePKM ( ) : pkm ) . Data ) ;
2015-12-26 18:26:42 +00:00
bool alreadyInit = fieldsInitialized ;
2015-11-06 06:59:55 +00:00
fieldsInitialized = false ;
2014-12-13 22:48:34 +00:00
Menu_Options . DropDown . Close ( ) ;
InitializeStrings ( ) ;
InitializeLanguage ( ) ;
2016-09-30 05:41:35 +00:00
string ProgramTitle = Text ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . TranslateInterface ( this , curlanguage ) ; // Translate the UI to language.
2016-09-30 05:41:35 +00:00
Text = ProgramTitle ;
2016-07-17 00:19:26 +00:00
// Recenter PKM SubEditors
2016-09-06 06:13:46 +00:00
FLP_PKMEditors . Location = new Point ( ( Tab_OTMisc . Width - FLP_PKMEditors . Width ) / 2 , FLP_PKMEditors . Location . Y ) ;
2016-01-24 18:19:30 +00:00
populateFields ( pk ) ; // put data back in form
2017-03-24 18:18:14 +00:00
fieldsInitialized | = alreadyInit ;
2014-12-13 22:48:34 +00:00
}
private void InitializeStrings ( )
2017-03-24 18:18:14 +00:00
{
2016-09-10 21:30:07 +00:00
string l = curlanguage ;
2017-01-08 07:54:09 +00:00
GameInfo . Strings = GameInfo . getStrings ( l ) ;
2014-06-28 21:22:05 +00:00
2017-03-22 04:40:33 +00:00
// Update Legality Strings
2017-04-09 23:38:29 +00:00
// Clipboard.SetText(string.Join(Environment.NewLine, Util.getLocalization(typeof(LegalityCheckStrings))));
2017-03-24 17:59:45 +00:00
Task . Run ( ( ) = > Util . setLocalization ( typeof ( LegalityCheckStrings ) ) ) ;
2017-03-22 04:40:33 +00:00
2014-12-13 22:48:34 +00:00
// Force an update to the met locations
2016-08-27 20:05:01 +00:00
origintrack = GameVersion . Unknown ;
2014-06-28 21:22:05 +00:00
2016-04-07 01:13:43 +00:00
// Update Legality Analysis strings
2017-01-08 07:54:09 +00:00
LegalityAnalysis . movelist = GameInfo . Strings . movelist ;
2017-04-10 00:43:05 +00:00
LegalityAnalysis . specieslist = GameInfo . Strings . specieslist ;
2016-04-07 01:13:43 +00:00
2015-11-06 06:59:55 +00:00
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.
2015-11-06 06:59:55 +00:00
fieldsInitialized = true ;
2016-06-20 04:22:43 +00:00
pkm . RefreshChecksum ( ) ;
2015-11-06 06:59:55 +00:00
// Load Data
2016-06-20 04:22:43 +00:00
populateFields ( pkm ) ;
2017-01-29 08:02:32 +00:00
TemplateFields ( ) ;
CB_BoxSelect . SelectedIndex = 0 ;
}
2017-05-11 02:24:58 +00:00
private static PKM loadTemplate ( )
{
if ( ! Directory . Exists ( TemplatePath ) )
return null ;
var blank = SAV . BlankPKM ;
string path = Path . Combine ( TemplatePath , new DirectoryInfo ( TemplatePath ) . Name + "." + blank . Extension ) ;
if ( ! File . Exists ( path ) | | ! PKX . getIsPKM ( new FileInfo ( path ) . Length ) )
return null ;
var pk = PKMConverter . getPKMfromBytes ( File . ReadAllBytes ( path ) , prefer : blank . Format ) ;
return PKMConverter . convertToFormat ( pk , SAV . BlankPKM . GetType ( ) , out path ) ; // no sneaky plz; reuse string
}
2017-01-29 08:02:32 +00:00
private void TemplateFields ( )
{
2017-05-11 02:24:58 +00:00
var template = loadTemplate ( ) ;
if ( template ! = null )
{ populateFields ( template ) ; return ; }
2017-02-04 05:48:43 +00:00
CB_GameOrigin . SelectedIndex = 0 ;
2017-01-29 08:02:32 +00:00
CB_Move1 . SelectedValue = 1 ;
TB_OT . Text = "PKHeX" ;
TB_TID . Text = 12345. ToString ( ) ;
TB_SID . Text = 54321. ToString ( ) ;
int curlang = Array . IndexOf ( GameInfo . lang_val , curlanguage ) ;
CB_Language . SelectedIndex = curlang > CB_Language . Items . Count - 1 ? 1 : curlang ;
CB_Ball . SelectedIndex = Math . Min ( 0 , CB_Ball . Items . Count - 1 ) ;
CB_Country . SelectedIndex = Math . Min ( 0 , CB_Country . Items . Count - 1 ) ;
CAL_MetDate . Value = CAL_EggDate . Value = DateTime . Today ;
2017-02-04 05:48:43 +00:00
CB_Species . SelectedValue = SAV . MaxSpeciesID ;
2017-01-29 08:02:32 +00:00
CHK_Nicknamed . Checked = false ;
2017-03-22 06:25:13 +00:00
lastData = null ;
2014-12-13 22:48:34 +00:00
}
private void InitializeLanguage ( )
{
2016-06-20 04:22:43 +00:00
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 07:18:27 +00:00
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" ) ;
2016-08-27 20:05:01 +00:00
2017-01-08 07:54:09 +00:00
GameInfo . InitializeDataSources ( GameInfo . Strings ) ;
2016-10-29 22:41:55 +00:00
2017-01-08 07:54:09 +00:00
CB_EncounterType . DataSource = Util . getCBList ( GameInfo . Strings . encountertypelist , new [ ] { 0 } , Legal . Gen4EncounterTypes ) ;
CB_HPType . DataSource = Util . getCBList ( GameInfo . Strings . types . Skip ( 1 ) . Take ( 16 ) . ToArray ( ) , null ) ;
2016-10-29 22:41:55 +00:00
CB_Nature . DataSource = new BindingSource ( GameInfo . NatureDataSource , null ) ;
2016-06-21 01:58:06 +00:00
populateFilteredDataSources ( ) ;
}
private void populateFilteredDataSources ( )
{
2017-01-08 07:54:09 +00:00
GameInfo . setItemDataSource ( HaX , SAV . MaxItemID , SAV . HeldItems , SAV . Generation , SAV . Version , GameInfo . Strings ) ;
2016-08-28 10:18:22 +00:00
if ( SAV . Generation > 1 )
2016-10-29 22:41:55 +00:00
CB_HeldItem . DataSource = new BindingSource ( GameInfo . ItemDataSource . Where ( i = > i . Value < = SAV . MaxItemID ) . ToList ( ) , null ) ;
2016-07-09 01:38:40 +00:00
2016-11-09 16:23:47 +00:00
var languages = Util . getUnsortedCBList ( "languages" ) ;
if ( SAV . Generation < 7 )
languages = languages . Where ( l = > l . Value < = 8 ) . ToList ( ) ; // Korean
CB_Language . DataSource = languages ;
2016-10-29 22:41:55 +00:00
CB_Ball . DataSource = new BindingSource ( GameInfo . BallDataSource . Where ( b = > b . Value < = SAV . MaxBallID ) . ToList ( ) , null ) ;
CB_Species . DataSource = new BindingSource ( GameInfo . SpeciesDataSource . Where ( s = > s . Value < = SAV . MaxSpeciesID ) . ToList ( ) , null ) ;
DEV_Ability . DataSource = new BindingSource ( GameInfo . AbilityDataSource . Where ( a = > a . Value < = SAV . MaxAbilityID ) . ToList ( ) , null ) ;
CB_GameOrigin . DataSource = new BindingSource ( GameInfo . VersionDataSource . Where ( g = > g . Value < = SAV . MaxGameID | | SAV . Generation > = 3 & & g . Value = = 15 ) . ToList ( ) , null ) ;
2015-03-09 00:41:13 +00:00
2014-12-14 07:18:27 +00:00
// Set the Move ComboBoxes too..
2017-02-14 05:20:10 +00:00
GameInfo . MoveDataSource = ( HaX ? GameInfo . HaXMoveDataSource : GameInfo . LegalMoveDataSource ) . Where ( m = > m . Value < = SAV . MaxMoveID ) . ToList ( ) ; // Filter Z-Moves if appropriate
2016-04-10 16:33:38 +00:00
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
{
2016-04-10 16:33:38 +00:00
cb . DisplayMember = "Text" ; cb . ValueMember = "Value" ;
2017-02-14 05:20:10 +00:00
cb . DataSource = new BindingSource ( GameInfo . MoveDataSource , null ) ;
2014-08-07 00:10:29 +00:00
}
2014-06-28 21:22:05 +00:00
}
2016-07-09 21:01:31 +00:00
private Action getFieldsfromPKM ;
private Func < PKM > getPKMfromFields ;
2017-03-22 06:25:13 +00:00
private byte [ ] lastData ;
2017-03-23 01:02:05 +00:00
private bool PKMIsUnsaved = > fieldsInitialized & & Menu_ModifyUnset . Checked & & ! loadingSAV & & lastData ! = null & & lastData . Any ( b = > b ! = 0 ) & & ! lastData . SequenceEqual ( preparePKM ( ) . Data ) ;
2017-01-15 00:43:16 +00:00
private void setPKMFormatMode ( int Format , GameVersion version )
{
byte [ ] extraBytes = new byte [ 0 ] ;
switch ( Format )
{
case 1 :
getFieldsfromPKM = populateFieldsPK1 ;
getPKMfromFields = preparePK1 ;
break ;
case 2 :
getFieldsfromPKM = populateFieldsPK2 ;
getPKMfromFields = preparePK2 ;
break ;
case 3 :
if ( version = = GameVersion . COLO )
{
getFieldsfromPKM = populateFieldsCK3 ;
getPKMfromFields = prepareCK3 ;
extraBytes = CK3 . ExtraBytes ;
break ;
}
if ( version = = GameVersion . XD )
{
getFieldsfromPKM = populateFieldsXK3 ;
getPKMfromFields = prepareXK3 ;
extraBytes = XK3 . ExtraBytes ;
break ;
}
getFieldsfromPKM = populateFieldsPK3 ;
getPKMfromFields = preparePK3 ;
extraBytes = PK3 . ExtraBytes ;
break ;
case 4 :
if ( 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 ;
break ;
case 7 :
getFieldsfromPKM = populateFieldsPK7 ;
getPKMfromFields = preparePK7 ;
extraBytes = PK7 . ExtraBytes ;
break ;
}
// Load Extra Byte List
2017-01-15 00:59:57 +00:00
GB_ExtraBytes . Visible = GB_ExtraBytes . Enabled = extraBytes . Length ! = 0 ;
if ( GB_ExtraBytes . Enabled )
2017-01-15 00:43:16 +00:00
{
CB_ExtraBytes . Items . Clear ( ) ;
foreach ( byte b in extraBytes )
CB_ExtraBytes . Items . Add ( "0x" + b . ToString ( "X2" ) ) ;
CB_ExtraBytes . SelectedIndex = 0 ;
}
}
2016-06-20 04:22:43 +00:00
public void populateFields ( PKM pk , bool focus = true )
2014-06-28 21:22:05 +00:00
{
2017-01-08 07:54:09 +00:00
if ( pk = = null ) { WinFormsUtil . Error ( "Attempted to load a null file." ) ; return ; }
2016-09-05 01:17:13 +00:00
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
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( $"Can't load Gen{pk.Format} to Gen{SAV.Generation} games." ) ; return ; }
2016-06-28 06:03:57 +00:00
2015-11-06 06:59:55 +00:00
bool oldInit = fieldsInitialized ;
2016-02-17 15:54:59 +00:00
fieldsInitialized = fieldsLoaded = false ;
2015-10-12 06:36:20 +00:00
if ( focus )
Tab_Main . Focus ( ) ;
2014-12-13 22:48:34 +00:00
2016-06-30 05:58:02 +00:00
pkm = pk . Clone ( ) ;
2016-07-09 21:01:31 +00:00
2016-06-20 04:22:43 +00:00
if ( fieldsInitialized & ! pkm . ChecksumValid )
2017-02-05 07:11:48 +00:00
WinFormsUtil . Alert ( "PKM File has an invalid checksum." ) ;
2016-07-09 21:01:31 +00:00
if ( pkm . Format ! = SAV . Generation ) // past gen format
2016-06-20 04:22:43 +00:00
{
2016-07-09 21:01:31 +00:00
string c ;
2016-09-26 23:14:11 +00:00
pkm = PKMConverter . convertToFormat ( pkm , SAV . PKMType , out c ) ;
2016-07-23 21:16:23 +00:00
if ( pk . Format ! = pkm . Format & & focus ) // converted
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Converted File." ) ;
2016-06-20 04:22:43 +00:00
}
2016-09-11 19:52:28 +00:00
try { getFieldsfromPKM ( ) ; }
catch { fieldsInitialized = oldInit ; throw ; }
2016-07-09 21:01:31 +00:00
2016-11-11 16:04:40 +00:00
CB_EncounterType . Visible = Label_EncounterType . Visible = pkm . Gen4 & & SAV . Generation < 7 ;
2016-06-20 04:22:43 +00:00
fieldsInitialized = oldInit ;
updateIVs ( null , null ) ;
updatePKRSInfected ( null , null ) ;
updatePKRSCured ( null , null ) ;
2016-12-12 04:50:38 +00:00
if ( HaX ) // Load original values from pk not pkm
2016-06-20 04:22:43 +00:00
{
2016-12-19 07:39:37 +00:00
MT_Level . Text = ( pk . Stat_HPMax ! = 0 ? pk . Stat_Level : PKX . getLevel ( pk . Species , pk . EXP ) ) . ToString ( ) ;
TB_EXP . Text = pk . EXP . ToString ( ) ;
2016-12-12 04:50:38 +00:00
MT_Form . Text = pk . AltForm . ToString ( ) ;
if ( pk . Stat_HPMax ! = 0 ) // stats present
2016-06-20 04:22:43 +00:00
{
2016-12-12 04:50:38 +00:00
Stat_HP . Text = pk . Stat_HPCurrent . ToString ( ) ;
Stat_ATK . Text = pk . Stat_ATK . ToString ( ) ;
Stat_DEF . Text = pk . Stat_DEF . ToString ( ) ;
Stat_SPA . Text = pk . Stat_SPA . ToString ( ) ;
Stat_SPD . Text = pk . Stat_SPD . ToString ( ) ;
Stat_SPE . Text = pk . Stat_SPE . ToString ( ) ;
2016-06-20 04:22:43 +00:00
}
}
fieldsLoaded = true ;
2016-09-05 21:26:21 +00:00
Label_HatchCounter . Visible = CHK_IsEgg . Checked & & SAV . Generation > 1 ;
Label_Friendship . Visible = ! CHK_IsEgg . Checked & & SAV . Generation > 1 ;
2016-06-20 04:22:43 +00:00
// Set the Preview Box
2017-01-12 01:55:42 +00:00
dragout . Image = pk . Sprite ( ) ;
2016-11-13 06:09:40 +00:00
setMarkings ( ) ;
2016-06-20 04:22:43 +00:00
updateLegality ( ) ;
2017-03-22 06:25:13 +00:00
lastData = preparePKM ( ) ? . Data ;
2016-06-20 04:22:43 +00:00
}
2014-12-25 00:20:39 +00:00
// General Use Functions shared by other Forms //
2015-09-21 03:34:09 +00:00
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 ;
2014-12-24 07:29:57 +00:00
// fix for Korean / Chinese being swapped
string cl = curlanguage + "" ;
2016-01-05 06:42:38 +00:00
cl = cl = = "zh" ? "ko" : cl = = "ko" ? "zh" : cl ;
2014-06-28 21:22:05 +00:00
2014-12-24 07:29:57 +00:00
CB . DataSource = Util . getCBList ( type , cl ) ;
2015-11-06 06:59:55 +00:00
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
}
2016-06-30 05:58:02 +00:00
private void setForms ( )
2014-12-13 22:48:34 +00:00
{
2017-01-08 07:54:09 +00:00
int species = WinFormsUtil . getIndex ( CB_Species ) ;
2016-10-22 16:16:08 +00:00
if ( SAV . Generation < 4 & & species ! = 201 )
2016-06-30 05:58:02 +00:00
{
Label_Form . Visible = CB_Form . Visible = CB_Form . Enabled = false ;
return ;
}
2016-07-28 01:08:08 +00:00
bool hasForms = SAV . Personal [ species ] . HasFormes | | new [ ] { 201 , 664 , 665 , 414 } . Contains ( species ) ;
2016-06-30 05:58:02 +00:00
CB_Form . Enabled = CB_Form . Visible = Label_Form . Visible = hasForms ;
2016-09-05 22:46:38 +00:00
2016-10-12 05:59:19 +00:00
if ( HaX & & SAV . Generation > = 4 )
2016-09-05 22:46:38 +00:00
Label_Form . Visible = true ;
2016-06-30 05:58:02 +00:00
if ( ! hasForms )
return ;
2017-01-08 07:54:09 +00:00
var ds = PKX . getFormList ( species , GameInfo . Strings . types , GameInfo . Strings . forms , gendersymbols , SAV . Generation ) . ToList ( ) ;
2016-11-10 06:19:52 +00:00
if ( ds . Count = = 1 & & string . IsNullOrEmpty ( ds [ 0 ] ) ) // empty (Alolan Totems)
CB_Form . Enabled = CB_Form . Visible = Label_Form . Visible = false ;
else CB_Form . DataSource = ds ;
2014-12-13 22:48:34 +00:00
}
2016-06-28 06:03:57 +00:00
private void setAbilityList ( )
2014-12-24 07:29:57 +00:00
{
2016-06-28 06:03:57 +00:00
if ( SAV . Generation < 3 ) // no abilities
2014-12-24 07:29:57 +00:00
return ;
2016-06-28 06:03:57 +00:00
int formnum = 0 ;
2017-01-08 07:54:09 +00:00
int species = WinFormsUtil . getIndex ( CB_Species ) ;
2016-06-28 06:03:57 +00:00
if ( SAV . Generation > 3 ) // has forms
formnum = CB_Form . SelectedIndex ;
2016-06-26 21:23:41 +00:00
2016-07-18 06:04:39 +00:00
int [ ] abils = SAV . Personal . getAbilities ( species , formnum ) ;
2016-09-11 06:12:22 +00:00
if ( abils [ 1 ] = = 0 & & SAV . Generation ! = 3 )
Implement PID-Ability corrections
Line 2211:
When the fields are loaded, if the user modifies the Ability on a <=Gen5
save file, if the ability is modified, the PID will be randomized to fit
the new PID.
When the Ability combobox is loaded, the personal entry may have 0 for
the ability2 (indicating same as ability1); if so, copy ability1 instead
of filtering it out.
When the Ability index is loaded, hidden ability is checked first, else
it tries to match: invalid, hidden (unflagged=illegal), if abilities
same use PIDAbility, else use the actual ability index.
2016-08-23 03:37:50 +00:00
abils [ 1 ] = abils [ 0 ] ;
2016-07-03 03:24:17 +00:00
string [ ] abilIdentifier = { " (1)" , " (2)" , " (H)" } ;
2017-01-08 07:54:09 +00:00
List < string > ability_list = abils . Where ( a = > a ! = 0 ) . Select ( ( t , i ) = > GameInfo . Strings . abilitylist [ t ] + abilIdentifier [ i ] ) . ToList ( ) ;
2016-07-05 06:53:35 +00:00
if ( ! ability_list . Any ( ) )
2017-01-08 07:54:09 +00:00
ability_list . Add ( GameInfo . Strings . abilitylist [ 0 ] + abilIdentifier [ 0 ] ) ;
2016-06-26 21:23:41 +00:00
2017-01-28 18:36:57 +00:00
bool tmp = fieldsLoaded ;
fieldsLoaded = false ;
2016-07-09 21:21:28 +00:00
int abil = CB_Ability . SelectedIndex ;
2016-06-28 06:03:57 +00:00
CB_Ability . DataSource = ability_list ;
2016-07-09 21:21:28 +00:00
CB_Ability . SelectedIndex = abil < 0 | | abil > = CB_Ability . Items . Count ? 0 : abil ;
2017-01-28 18:36:57 +00:00
fieldsLoaded = tmp ;
2016-06-26 21:23:41 +00:00
}
2014-12-24 07:29:57 +00:00
// PKX Data Calculation Functions //
2016-07-19 03:25:54 +00:00
private void setIsShiny ( object sender )
2014-12-24 07:29:57 +00:00
{
2016-07-19 03:25:54 +00:00
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 ) ;
2016-07-18 06:40:40 +00:00
bool isShiny = pkm . IsShiny ;
2015-01-01 19:38:37 +00:00
2014-12-24 07:29:57 +00:00
// Set the Controls
2017-01-25 05:01:32 +00:00
BTN_Shinytize . Visible = BTN_Shinytize . Enabled = ! isShiny ;
Label_IsShiny . Visible = isShiny ;
2014-12-24 07:29:57 +00:00
// Refresh Markings (for Shiny Star if applicable)
setMarkings ( ) ;
}
2014-12-13 22:48:34 +00:00
private void setMarkings ( )
{
2017-01-26 06:51:52 +00:00
Func < bool , double > getOpacity = b = > b ? 1 : 0.175 ;
2014-12-13 22:48:34 +00:00
PictureBox [ ] pba = { PB_Mark1 , PB_Mark2 , PB_Mark3 , PB_Mark4 , PB_Mark5 , PB_Mark6 } ;
2016-10-31 02:15:48 +00:00
for ( int i = 0 ; i < pba . Length ; i + + )
2017-01-26 06:51:52 +00:00
pba [ i ] . Image = ImageUtil . ChangeOpacity ( pba [ i ] . InitialImage , getOpacity ( pkm . Markings [ i ] ! = 0 ) ) ;
2015-09-24 03:29:31 +00:00
2017-01-26 06:51:52 +00:00
PB_MarkShiny . Image = ImageUtil . ChangeOpacity ( PB_MarkShiny . InitialImage , getOpacity ( ! BTN_Shinytize . Enabled ) ) ;
PB_MarkCured . Image = ImageUtil . ChangeOpacity ( PB_MarkCured . InitialImage , getOpacity ( CHK_Cured . Checked ) ) ;
2016-10-30 23:40:19 +00:00
2017-01-26 06:51:52 +00:00
PB_MarkPentagon . Image = ImageUtil . ChangeOpacity ( PB_MarkPentagon . InitialImage , getOpacity ( pkm . Gen6 ) ) ;
2016-10-31 02:15:48 +00:00
// Gen7 Markings
if ( pkm . Format ! = 7 )
return ;
2017-01-26 06:51:52 +00:00
PB_MarkAlola . Image = ImageUtil . ChangeOpacity ( PB_MarkAlola . InitialImage , getOpacity ( pkm . Gen7 ) ) ;
PB_MarkVC . Image = ImageUtil . ChangeOpacity ( PB_MarkVC . InitialImage , getOpacity ( pkm . VC ) ) ;
PB_MarkHorohoro . Image = ImageUtil . ChangeOpacity ( PB_MarkHorohoro . InitialImage , getOpacity ( pkm . Horohoro ) ) ;
2017-01-24 15:12:14 +00:00
2016-10-31 02:15:48 +00:00
for ( int i = 0 ; i < pba . Length ; i + + )
{
switch ( pkm . Markings [ i ] )
{
case 1 :
2017-01-12 01:55:42 +00:00
pba [ i ] . Image = ImageUtil . ChangeAllColorTo ( pba [ i ] . Image , Color . FromArgb ( 000 , 191 , 255 ) ) ;
2016-10-31 02:15:48 +00:00
break ;
case 2 :
2017-01-12 01:55:42 +00:00
pba [ i ] . Image = ImageUtil . ChangeAllColorTo ( pba [ i ] . Image , Color . FromArgb ( 255 , 117 , 179 ) ) ;
2016-10-31 02:15:48 +00:00
break ;
}
}
2014-12-13 22:48:34 +00:00
}
2015-02-25 04:10:47 +00:00
// Clicked Label Shortcuts //
2017-03-12 23:36:23 +00:00
private bool QR6Notified ;
2015-02-25 04:10:47 +00:00
private void clickQR ( object sender , EventArgs e )
{
2015-02-27 08:40:57 +00:00
if ( ModifierKeys = = Keys . Alt )
{
// Fetch data from QR code...
2016-06-20 04:22:43 +00:00
byte [ ] ekx = QR . getQRData ( ) ;
2015-03-14 02:59:51 +00:00
if ( ekx = = null ) return ;
2016-10-12 05:59:19 +00:00
2017-01-28 07:33:36 +00:00
PKM pk = PKMConverter . getPKMfromBytes ( ekx , prefer : SAV . Generation ) ;
2017-01-08 07:54:09 +00:00
if ( pk = = null ) { WinFormsUtil . Alert ( "Decoded data not a valid PKM." , $"QR Data Size: {ekx.Length}" ) ; }
2016-10-12 05:59:19 +00:00
else
{
if ( ! pk . Valid | | pk . Species < = 0 )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Invalid data detected." ) ; return ; }
2015-03-14 02:59:51 +00:00
2016-10-12 05:59:19 +00:00
string c ; PKM pkz = PKMConverter . convertToFormat ( pk , SAV . PKMType , out c ) ;
if ( pkz = = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( c ) ; return ; }
2016-10-12 05:59:19 +00:00
populateFields ( pkz ) ;
}
2015-02-26 06:39:29 +00:00
}
2015-02-27 08:40:57 +00:00
else
2015-02-26 07:12:38 +00:00
{
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) ) return ;
2016-06-20 04:22:43 +00:00
PKM pkx = preparePKM ( ) ;
2017-01-26 06:51:52 +00:00
2016-11-16 08:11:41 +00:00
Image qr ;
switch ( pkx . Format )
{
case 7 :
2017-01-12 01:55:42 +00:00
qr = QR . GenerateQRCode7 ( ( PK7 ) pkx ) ;
2016-11-16 08:11:41 +00:00
break ;
default :
2017-03-11 04:35:18 +00:00
if ( pkx . Format = = 6 & & ! QR6Notified ) // hint that the user should not be using QR6 injection
{
WinFormsUtil . Alert ( "QR codes are deprecated in favor of other methods." ,
"Consider utilizing homebrew or on-the-fly RAM editing custom firmware (PKMN-NTR)." ) ;
QR6Notified = true ;
}
qr = QR . getQRImage ( pkx . EncryptedBoxData , QR . getQRServer ( pkx . Format ) ) ;
2016-11-17 05:16:44 +00:00
break ;
2016-11-16 08:11:41 +00:00
}
2015-03-14 02:59:51 +00:00
if ( qr = = null ) return ;
2015-02-27 08:40:57 +00:00
2017-02-05 20:55:17 +00:00
var sprite = dragout . Image ;
var la = new LegalityAnalysis ( pkx ) ;
if ( la . Parsed )
{
var img = la . Valid ? Resources . valid : Resources . warn ;
sprite = ImageUtil . LayerImage ( sprite , img , 24 , 0 , 1 ) ;
}
2016-01-24 18:19:30 +00:00
string [ ] r = pkx . QRText ;
2017-02-05 20:55:17 +00:00
string refer = $"PKHeX ({Resources.ProgramVersion})" ;
new QR ( qr , sprite , r [ 0 ] , r [ 1 ] , r [ 2 ] , $"{refer} ({pkx.GetType().Name})" , pkx ) . ShowDialog ( ) ;
2015-02-26 07:12:38 +00:00
}
2015-02-25 04:10:47 +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
2016-06-20 04:22:43 +00:00
TB_Friendship . Text = pkm . CurrentFriendship . ToString ( ) ;
2015-03-11 01:44:51 +00:00
else
2016-07-18 06:40:40 +00:00
TB_Friendship . Text = TB_Friendship . Text = = "255" ? SAV . Personal [ pkm . Species ] . BaseFriendship . ToString ( ) : "255" ;
2014-12-13 22:48:34 +00:00
}
2017-02-26 16:08:28 +00:00
private void clickLevel ( object sender , EventArgs e )
{
if ( ModifierKeys = = Keys . Control )
{
( ( MaskedTextBox ) sender ) . Text = "100" ;
}
}
2014-12-14 19:06:17 +00:00
private void clickGender ( object sender , EventArgs e )
2014-12-13 22:48:34 +00:00
{
// Get Gender Threshold
2017-01-08 07:54:09 +00:00
int gt = SAV . Personal . getFormeEntry ( WinFormsUtil . getIndex ( CB_Species ) , CB_Form . SelectedIndex ) . Gender ;
2014-12-13 22:48:34 +00:00
if ( gt = = 255 | | gt = = 0 | | gt = = 254 ) // Single gender/genderless
return ;
2015-03-11 01:44:51 +00:00
if ( gt > = 255 ) return ;
2015-08-07 04:16:25 +00:00
// 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 ;
2016-12-23 06:46:57 +00:00
if ( SAV . Generation = = 2 )
do { TB_ATKIV . Text = ( Util . rnd32 ( ) & SAV . MaxIV ) . ToString ( ) ; } while ( PKX . getGender ( Label_Gender . Text ) ! = newGender ) ;
else if ( SAV . Generation < = 4 )
2016-07-29 05:54:29 +00:00
{
2017-01-08 07:54:09 +00:00
pkm . Species = WinFormsUtil . getIndex ( CB_Species ) ;
pkm . Version = WinFormsUtil . getIndex ( CB_GameOrigin ) ;
pkm . Nature = WinFormsUtil . 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 ;
2016-06-20 04:22:43 +00:00
Label_Gender . Text = gendersymbols [ pkm . Gender ] ;
Label_Gender . ForeColor = pkm . Gender = = 2 ? Label_Species . ForeColor : ( pkm . Gender = = 1 ? Color . Red : Color . Blue ) ;
2015-03-11 01:44:51 +00:00
if ( PKX . getGender ( CB_Form . Text ) < 2 ) // Gendered Forms
CB_Form . SelectedIndex = PKX . getGender ( Label_Gender . Text ) ;
2015-02-28 05:51:19 +00:00
2015-03-11 01:44:51 +00:00
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
{
2017-01-08 07:54:09 +00:00
CB_PPu1 . SelectedIndex = ModifierKeys ! = Keys . Control & & WinFormsUtil . getIndex ( CB_Move1 ) > 0 ? 3 : 0 ;
CB_PPu2 . SelectedIndex = ModifierKeys ! = Keys . Control & & WinFormsUtil . getIndex ( CB_Move2 ) > 0 ? 3 : 0 ;
CB_PPu3 . SelectedIndex = ModifierKeys ! = Keys . Control & & WinFormsUtil . getIndex ( CB_Move3 ) > 0 ? 3 : 0 ;
CB_PPu4 . SelectedIndex = ModifierKeys ! = Keys . Control & & WinFormsUtil . 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 } ;
2016-06-20 04:22:43 +00:00
int index = Array . IndexOf ( pba , sender ) ;
2016-10-31 02:15:48 +00:00
// Handling Gens 3-6
int [ ] markings = pkm . Markings ;
switch ( pkm . Format )
{
case 3 :
case 4 :
case 5 :
case 6 : // on/off
markings [ index ] ^ = 1 ; // toggle
pkm . Markings = markings ;
break ;
case 7 : // 0 (none) | 1 (blue) | 2 (pink)
markings [ index ] = ( markings [ index ] + 1 ) % 3 ; // cycle
pkm . Markings = markings ;
break ;
default :
return ;
}
2014-12-13 22:48:34 +00:00
setMarkings ( ) ;
}
2015-09-27 17:00:45 +00:00
private void clickStatLabel ( object sender , MouseEventArgs e )
2015-09-26 04:56:15 +00:00
{
if ( ! ( ModifierKeys = = Keys . Control | | ModifierKeys = = Keys . Alt ) )
return ;
2016-09-06 23:46:00 +00:00
if ( sender = = Label_SPC )
sender = Label_SPA ;
2016-02-24 22:59:03 +00:00
int index = Array . IndexOf ( new [ ] { Label_HP , Label_ATK , Label_DEF , Label_SPA , Label_SPD , Label_SPE } , sender ) ;
2015-09-26 04:56:15 +00:00
if ( ModifierKeys = = Keys . Alt ) // EV
{
2016-09-06 23:46:00 +00:00
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 ( ) ;
2015-09-26 04:56:15 +00:00
}
else
2015-10-24 23:33:44 +00:00
new [ ] { TB_HPIV , TB_ATKIV , TB_DEFIV , TB_SPAIV , TB_SPDIV , TB_SPEIV } [ index ] . Text =
2016-09-06 23:46:00 +00:00
( e . Button = = MouseButtons . Left ? SAV . MaxIV : 0 ) . ToString ( ) ;
2015-09-26 04:56:15 +00:00
}
2015-09-27 17:00:45 +00:00
private void clickIV ( object sender , EventArgs e )
{
if ( ModifierKeys = = Keys . Control )
2016-11-11 10:00:47 +00:00
if ( SAV . Generation < 7 )
( ( MaskedTextBox ) sender ) . Text = SAV . MaxIV . ToString ( ) ;
else
{
var index = Array . IndexOf ( new [ ] { TB_HPIV , TB_ATKIV , TB_DEFIV , TB_SPAIV , TB_SPDIV , TB_SPEIV } , sender ) ;
2017-01-26 06:51:52 +00:00
pkm . HyperTrainInvert ( index ) ;
2016-11-11 10:00:47 +00:00
updateIVs ( sender , e ) ;
}
2015-09-27 17:00:45 +00:00
else if ( ModifierKeys = = Keys . Alt )
2016-07-18 18:51:26 +00:00
( ( MaskedTextBox ) sender ) . Text = 0. ToString ( ) ;
2015-09-27 17:00:45 +00:00
}
private void clickEV ( object sender , EventArgs e )
{
2016-09-06 23:46:00 +00:00
MaskedTextBox mt = ( MaskedTextBox ) sender ;
2015-09-27 17:00:45 +00:00
if ( ModifierKeys = = Keys . Control ) // EV
2016-09-06 23:46:00 +00:00
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 ( ) ;
2015-09-27 17:00:45 +00:00
else if ( ModifierKeys = = Keys . Alt )
2016-09-06 23:46:00 +00:00
mt . Text = 0. ToString ( ) ;
2015-09-27 17:00:45 +00:00
}
2014-12-14 19:06:17 +00:00
private void clickOT ( object sender , EventArgs e )
2014-12-13 22:48:34 +00:00
{
2016-01-31 07:03:43 +00:00
if ( ! SAV . Exportable )
return ;
2015-10-24 03:13:32 +00:00
// Get Save Information
2016-01-31 07:03:43 +00:00
TB_OT . Text = SAV . OT ;
Label_OTGender . Text = gendersymbols [ SAV . Gender % 2 ] ;
2016-05-06 01:47:40 +00:00
Label_OTGender . ForeColor = SAV . Gender = = 1 ? Color . Red : Color . Blue ;
2016-11-08 16:43:57 +00:00
TB_TID . Text = SAV . TID . ToString ( "00000" ) ;
TB_SID . Text = SAV . SID . ToString ( "00000" ) ;
2016-06-20 04:22:43 +00:00
if ( SAV . Game > = 0 )
CB_GameOrigin . SelectedValue = SAV . Game ;
if ( SAV . Language > = 0 )
CB_Language . SelectedValue = SAV . Language ;
if ( SAV . HasGeolocation )
{
CB_3DSReg . SelectedValue = SAV . ConsoleRegion ;
2017-03-24 01:10:14 +00:00
CB_Country . SelectedValue = SAV . Country ;
CB_SubRegion . SelectedValue = SAV . SubRegion ;
2016-06-20 04:22:43 +00:00
}
2015-03-11 01:44:51 +00:00
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
{
2014-12-20 19:27:29 +00:00
if ( TB_OTt2 . Text . Length > 0 )
2016-01-31 07:03:43 +00:00
Label_CTGender . Text = gendersymbols [ SAV . Gender % 2 ] ;
2014-12-20 19:27:29 +00:00
}
private void clickGT ( object sender , EventArgs e )
{
2016-06-20 04:22:43 +00:00
if ( ! GB_nOT . Visible )
return ;
2016-01-24 18:19:30 +00:00
if ( sender = = GB_OT )
2014-12-20 19:27:29 +00:00
{
2016-06-20 04:22:43 +00:00
pkm . CurrentHandler = 0 ;
2014-12-20 19:27:29 +00:00
GB_OT . BackgroundImage = mixedHighlight ;
GB_nOT . BackgroundImage = null ;
}
else if ( TB_OTt2 . Text . Length > 0 )
{
2016-06-20 04:22:43 +00:00
pkm . CurrentHandler = 1 ;
2014-12-20 19:27:29 +00:00
GB_OT . BackgroundImage = null ;
GB_nOT . BackgroundImage = mixedHighlight ;
}
2016-06-20 04:22:43 +00:00
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)
2015-08-07 04:16:25 +00:00
{
int gender = PKX . getGender ( lbl . Text ) ^ 1 ;
lbl . Text = gendersymbols [ gender ] ;
2016-01-05 06:42:38 +00:00
lbl . ForeColor = gender = = 1 ? Color . Red : Color . Blue ;
2015-08-07 04:16:25 +00:00
}
2014-12-13 22:48:34 +00:00
}
2015-06-28 21:34:38 +00:00
private void clickMoves ( object sender , EventArgs e )
{
2017-03-06 04:00:27 +00:00
updateLegality ( skipMoveRepop : true ) ;
2016-11-15 06:13:15 +00:00
if ( sender = = GB_CurrentMoves )
{
bool random = ModifierKeys = = Keys . Control ;
2016-11-27 04:02:44 +00:00
int [ ] m = Legality . getSuggestedMoves ( tm : random , tutor : random , reminder : random ) ;
2016-11-15 06:16:51 +00:00
if ( m = = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Suggestions are not enabled for this PKM format." ) ; return ; }
2016-11-15 06:16:51 +00:00
2016-11-15 06:13:15 +00:00
if ( random )
Util . Shuffle ( m ) ;
if ( m . Length > 4 )
m = m . Skip ( m . Length - 4 ) . ToArray ( ) ;
2016-11-15 07:02:27 +00:00
Array . Resize ( ref m , 4 ) ;
2016-11-17 04:42:29 +00:00
if ( pkm . Moves . SequenceEqual ( m ) )
return ;
2017-01-08 07:54:09 +00:00
string r = string . Join ( Environment . NewLine , m . Select ( v = > v > = GameInfo . Strings . movelist . Length ? "ERROR" : GameInfo . Strings . movelist [ v ] ) ) ;
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Apply suggested current moves?" , r ) )
2016-11-15 06:13:15 +00:00
return ;
CB_Move1 . SelectedValue = m [ 0 ] ;
CB_Move2 . SelectedValue = m [ 1 ] ;
CB_Move3 . SelectedValue = m [ 2 ] ;
CB_Move4 . SelectedValue = m [ 3 ] ;
}
else if ( sender = = GB_RelearnMoves )
{
int [ ] m = Legality . getSuggestedRelearn ( ) ;
2016-12-30 20:54:52 +00:00
if ( ! pkm . WasEgg & & ! pkm . WasEvent & & ! pkm . WasEventEgg & & ! pkm . WasLink )
{
var encounter = Legality . getSuggestedMetInfo ( ) ;
if ( encounter ! = null )
m = encounter . Relearn ;
}
2016-11-17 04:42:29 +00:00
if ( pkm . RelearnMoves . SequenceEqual ( m ) )
return ;
2017-01-08 07:54:09 +00:00
string r = string . Join ( Environment . NewLine , m . Select ( v = > v > = GameInfo . Strings . movelist . Length ? "ERROR" : GameInfo . Strings . movelist [ v ] ) ) ;
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Apply suggested relearn moves?" , r ) )
2016-11-15 06:13:15 +00:00
return ;
CB_RelearnMove1 . SelectedValue = m [ 0 ] ;
CB_RelearnMove2 . SelectedValue = m [ 1 ] ;
CB_RelearnMove3 . SelectedValue = m [ 2 ] ;
CB_RelearnMove4 . SelectedValue = m [ 3 ] ;
}
2015-06-28 21:34:38 +00:00
2016-03-25 07:10:11 +00:00
updateLegality ( ) ;
2015-06-28 21:34:38 +00:00
}
2016-11-27 07:23:45 +00:00
private void clickMetLocation ( object sender , EventArgs e )
{
if ( HaX )
return ;
2016-12-01 06:15:56 +00:00
pkm = preparePKM ( ) ;
2017-03-06 04:00:27 +00:00
updateLegality ( skipMoveRepop : true ) ;
2017-02-15 01:33:57 +00:00
if ( Legality . Valid )
return ;
2016-11-27 07:23:45 +00:00
var encounter = Legality . getSuggestedMetInfo ( ) ;
2017-02-15 01:33:57 +00:00
if ( encounter = = null | | ( pkm . Format > = 3 & & encounter . Location < 0 ) )
2016-11-27 07:23:45 +00:00
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Unable to provide a suggestion." ) ;
2016-11-27 07:23:45 +00:00
return ;
}
int level = encounter . Level ;
int location = encounter . Location ;
2016-12-01 06:15:56 +00:00
int minlvl = Legal . getLowestLevel ( pkm , encounter . Species ) ;
2017-02-15 01:33:57 +00:00
if ( minlvl = = 0 )
minlvl = level ;
if ( pkm . CurrentLevel > = minlvl & & pkm . Met_Level = = level & & pkm . Met_Location = = location )
2016-11-27 07:23:45 +00:00
return ;
2017-02-15 08:11:12 +00:00
if ( minlvl < level )
minlvl = level ;
2016-11-27 07:23:45 +00:00
2017-02-15 01:33:57 +00:00
var suggestion = new List < string > { "Suggested:" } ;
if ( pkm . Format > = 3 )
{
var met_list = GameInfo . getLocationList ( ( GameVersion ) pkm . Version , SAV . Generation , egg : false ) ;
var locstr = met_list . FirstOrDefault ( loc = > loc . Value = = location ) ? . Text ;
suggestion . Add ( $"Met Location: {locstr}" ) ;
suggestion . Add ( $"Met Level: {level}" ) ;
}
2016-12-01 06:15:56 +00:00
if ( pkm . CurrentLevel < minlvl )
2017-02-15 01:33:57 +00:00
suggestion . Add ( $"Current Level: {minlvl}" ) ;
if ( suggestion . Count = = 1 ) // no suggestion
return ;
2016-11-27 07:23:45 +00:00
2017-02-15 01:33:57 +00:00
string suggest = string . Join ( Environment . NewLine , suggestion ) ;
if ( WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , suggest ) ! = DialogResult . Yes )
2016-11-27 07:23:45 +00:00
return ;
2017-02-15 01:33:57 +00:00
if ( pkm . Format > = 3 )
{
TB_MetLevel . Text = level . ToString ( ) ;
CB_MetLocation . SelectedValue = location ;
}
2016-12-01 06:15:56 +00:00
if ( pkm . CurrentLevel < minlvl )
TB_Level . Text = minlvl . ToString ( ) ;
pkm = preparePKM ( ) ;
updateLegality ( ) ;
2016-11-27 07:23:45 +00:00
}
2014-12-13 22:48:34 +00:00
// Prompted Updates of PKX Functions //
2015-03-11 01:44:51 +00:00
private bool changingFields ;
2016-11-27 03:41:17 +00:00
private void updateBall ( object sender , EventArgs e )
{
2017-01-12 01:55:42 +00:00
PB_Ball . Image = PKMUtil . getBallSprite ( WinFormsUtil . getIndex ( CB_Ball ) ) ;
2016-11-27 03:41:17 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateEXPLevel ( object sender , EventArgs e )
{
2016-10-09 23:39:31 +00:00
if ( changingFields | | ! fieldsInitialized ) return ;
2014-12-20 04:22:15 +00:00
2016-02-01 04:44:30 +00:00
changingFields = true ;
2016-01-31 07:03:43 +00:00
if ( sender = = TB_EXP )
2014-12-13 22:48:34 +00:00
{
// Change the Level
2016-01-09 20:39:18 +00:00
uint EXP = Util . ToUInt32 ( TB_EXP . Text ) ;
2017-01-08 07:54:09 +00:00
int Species = WinFormsUtil . getIndex ( CB_Species ) ;
2016-02-01 04:44:30 +00:00
int Level = PKX . getLevel ( Species , EXP ) ;
2015-09-25 02:54:50 +00:00
if ( Level = = 100 )
2016-02-01 04:44:30 +00:00
EXP = PKX . getEXP ( 100 , Species ) ;
2014-12-20 04:22:15 +00:00
2015-09-25 02:54:50 +00:00
TB_Level . Text = Level . ToString ( ) ;
2016-12-19 07:39:37 +00:00
if ( ! HaX )
2015-09-25 02:54:50 +00:00
TB_EXP . Text = EXP . ToString ( ) ;
2016-12-19 07:39:37 +00:00
else if ( Level < = 100 & & Util . ToInt32 ( MT_Level . Text ) < = 100 )
2015-09-25 02:54:50 +00:00
MT_Level . Text = Level . ToString ( ) ;
2014-12-13 22:48:34 +00:00
}
2014-12-20 04:22:15 +00:00
else
2014-12-13 22:48:34 +00:00
{
// Change the XP
2016-12-19 07:39:37 +00:00
int Level = Util . ToInt32 ( ( HaX ? MT_Level : TB_Level ) . Text ) ;
2015-09-25 02:54:50 +00:00
if ( Level > 100 ) TB_Level . Text = "100" ;
2016-01-03 04:22:53 +00:00
if ( Level > byte . MaxValue ) MT_Level . Text = "255" ;
2014-12-13 22:48:34 +00:00
2016-12-19 07:39:37 +00:00
if ( Level < = 100 )
2017-01-08 07:54:09 +00:00
TB_EXP . Text = PKX . getEXP ( Level , WinFormsUtil . getIndex ( CB_Species ) ) . ToString ( ) ;
2014-12-13 22:48:34 +00:00
}
2015-03-09 00:41:13 +00:00
changingFields = false ;
2016-10-09 23:59:55 +00:00
if ( fieldsLoaded ) // store values back
2016-08-28 10:18:22 +00:00
{
2016-07-30 02:38:16 +00:00
pkm . EXP = Util . ToUInt32 ( TB_EXP . Text ) ;
2016-12-19 07:39:37 +00:00
pkm . Stat_Level = Util . ToInt32 ( ( HaX ? MT_Level : TB_Level ) . Text ) ;
2016-08-28 10:18:22 +00:00
}
2014-12-13 22:48:34 +00:00
updateStats ( ) ;
2016-02-28 02:10:02 +00:00
updateLegality ( ) ;
2014-12-13 22:48:34 +00:00
}
2015-03-09 00:41:13 +00:00
private void updateHPType ( object sender , EventArgs e )
{
2015-11-06 06:59:55 +00:00
if ( changingFields | | ! fieldsInitialized ) return ;
2015-03-09 00:41:13 +00:00
changingFields = true ;
2015-09-25 02:54:50 +00:00
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
2015-09-25 02:54:50 +00:00
// Change IVs to match the new Hidden Power
2017-01-08 07:54:09 +00:00
int [ ] newIVs = PKX . setHPIVs ( WinFormsUtil . getIndex ( CB_HPType ) , ivs ) ;
2015-09-25 02:54:50 +00:00
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 )
{
2015-11-06 06:59:55 +00:00
if ( changingFields | | ! fieldsInitialized ) return ;
2016-08-28 10:18:22 +00:00
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
2015-09-24 03:29:31 +00:00
// Update IVs
2016-06-20 04:22:43 +00:00
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 ) ;
2016-08-28 10:18:22 +00:00
2016-11-11 10:00:47 +00:00
var IV_Boxes = new [ ] { TB_HPIV , TB_ATKIV , TB_DEFIV , TB_SPAIV , TB_SPDIV , TB_SPEIV } ;
var HT_Vals = new [ ] { pkm . HT_HP , pkm . HT_ATK , pkm . HT_DEF , pkm . HT_SPA , pkm . HT_SPD , pkm . HT_SPE } ;
for ( int i = 0 ; i < IV_Boxes . Length ; i + + )
if ( HT_Vals [ i ] )
IV_Boxes [ i ] . BackColor = Color . LightGreen ;
else
IV_Boxes [ i ] . ResetBackColor ( ) ;
2016-08-28 10:18:22 +00:00
if ( SAV . Generation < 3 )
{
2016-09-11 00:14:25 +00:00
TB_HPIV . Text = pkm . IV_HP . ToString ( ) ;
2016-09-04 06:45:10 +00:00
TB_SPDIV . Text = TB_SPAIV . Text ;
2016-09-02 21:20:39 +00:00
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 ) ;
2016-10-22 17:38:33 +00:00
if ( pkm . Species = = 201 & & e ! = null ) // Unown
CB_Form . SelectedIndex = pkm . AltForm ;
2016-09-02 21:20:39 +00:00
}
2017-01-25 05:01:32 +00:00
setIsShiny ( null ) ;
getQuickFiller ( dragout ) ;
2016-08-28 10:18:22 +00:00
}
2015-09-25 02:54:50 +00:00
2016-06-20 04:22:43 +00:00
CB_HPType . SelectedValue = pkm . HPType ;
2015-09-24 03:29:31 +00:00
changingFields = false ;
2014-06-28 21:22:05 +00:00
2015-09-24 03:29:31 +00:00
// Potential Reading
2016-12-06 01:42:19 +00:00
L_Potential . Text = ( unicode
2015-09-24 03:29:31 +00:00
? new [ ] { "★☆☆☆" , "★★☆☆" , "★★★☆" , "★★★★" }
: new [ ] { "+" , "++" , "+++" , "++++" }
2016-06-20 04:22:43 +00:00
) [ pkm . PotentialRating ] ;
2015-09-24 03:29:31 +00:00
2016-06-20 04:22:43 +00:00
TB_IVTotal . Text = pkm . IVs . Sum ( ) . ToString ( ) ;
2014-06-28 21:22:05 +00:00
2016-06-26 21:23:41 +00:00
int characteristic = pkm . Characteristic ;
2016-06-28 06:03:57 +00:00
L_Characteristic . Visible = Label_CharacteristicPrefix . Visible = characteristic > - 1 ;
2016-06-26 21:23:41 +00:00
if ( characteristic > - 1 )
2017-01-08 07:54:09 +00:00
L_Characteristic . Text = GameInfo . Strings . characteristics [ pkm . Characteristic ] ;
2014-12-13 22:48:34 +00:00
updateStats ( ) ;
}
private void updateEVs ( object sender , EventArgs e )
{
2016-07-21 03:40:03 +00:00
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
2015-09-24 03:29:31 +00:00
changingFields = true ;
2016-07-21 03:40:03 +00:00
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 ;
2016-07-21 03:40:03 +00:00
int evtotal = pkm . EVs . Sum ( ) ;
2014-12-13 22:48:34 +00:00
if ( evtotal > 510 ) // Background turns Red
2015-01-01 19:38:37 +00:00
TB_EVTotal . BackColor = Color . Red ;
2014-12-13 22:48:34 +00:00
else if ( evtotal = = 510 ) // Maximum EVs
2015-01-01 19:38:37 +00:00
TB_EVTotal . BackColor = Color . Honeydew ;
2015-09-24 03:29:31 +00:00
else if ( evtotal = = 508 ) // Fishy EVs
TB_EVTotal . BackColor = Color . LightYellow ;
2016-04-29 04:43:16 +00:00
else TB_EVTotal . BackColor = TB_IVTotal . BackColor ;
2014-12-13 22:48:34 +00:00
TB_EVTotal . Text = evtotal . ToString ( ) ;
2016-12-31 01:23:59 +00:00
EVTip . SetToolTip ( TB_EVTotal , $"Remaining: {510 - evtotal}" ) ;
2015-09-24 03:29:31 +00:00
changingFields = false ;
2014-12-13 22:48:34 +00:00
updateStats ( ) ;
}
private void updateRandomIVs ( object sender , EventArgs e )
{
2015-09-24 03:29:31 +00:00
changingFields = true ;
2015-03-12 15:25:27 +00:00
if ( ModifierKeys = = Keys . Control | | ModifierKeys = = Keys . Shift )
2014-12-13 22:48:34 +00:00
{
// Max IVs
2016-08-28 10:18:22 +00:00
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
{
2016-11-27 17:26:58 +00:00
bool IV3 = Legal . Legends . Contains ( pkm . Species ) | | Legal . SubLegends . Contains ( pkm . Species ) ;
2016-11-29 23:11:40 +00:00
2016-11-27 17:26:58 +00:00
int [ ] IVs = new int [ 6 ] ;
2016-11-29 23:11:40 +00:00
for ( int i = 0 ; i < 6 ; i + + )
IVs [ i ] = ( int ) ( Util . rnd32 ( ) & SAV . MaxIV ) ;
if ( IV3 )
for ( int i = 0 ; i < 3 ; i + + )
IVs [ i ] = SAV . MaxIV ;
Util . Shuffle ( IVs ) ; // Randomize IV order
2016-11-27 17:26:58 +00:00
var IVBoxes = new [ ] { TB_HPIV , TB_ATKIV , TB_DEFIV , TB_SPAIV , TB_SPDIV , TB_SPEIV } ;
for ( int i = 0 ; i < 6 ; i + + )
IVBoxes [ i ] . Text = IVs [ i ] . ToString ( ) ;
2014-12-13 22:48:34 +00:00
}
2015-09-24 03:29:31 +00:00
changingFields = false ;
2016-10-22 17:38:33 +00:00
updateIVs ( null , e ) ;
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 ;
2017-01-26 06:51:52 +00:00
var tb = new [ ] { TB_HPEV , TB_ATKEV , TB_DEFEV , TB_SPAEV , TB_SPDEV , TB_SPEEV } ;
bool zero = ModifierKeys = = Keys . Control | | ModifierKeys = = Keys . Shift ;
var evs = zero ? new uint [ 6 ] : PKX . getRandomEVs ( SAV . Generation ) ;
for ( int i = 0 ; i < 6 ; i + + )
tb [ i ] . Text = evs [ i ] . 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 )
{
2017-02-27 16:59:20 +00:00
if ( pkm . Format < 3 )
return ;
2016-07-30 05:30:06 +00:00
if ( fieldsLoaded )
pkm . PID = Util . getHEXval ( TB_PID . Text ) ;
2016-10-12 05:59:19 +00:00
2016-07-30 05:30:06 +00:00
if ( sender = = Label_Gender )
pkm . setPIDGender ( pkm . Gender ) ;
2017-01-08 07:54:09 +00:00
else if ( sender = = CB_Nature & & pkm . Nature ! = WinFormsUtil . getIndex ( CB_Nature ) )
pkm . setPIDNature ( WinFormsUtil . getIndex ( CB_Nature ) ) ;
2016-07-30 05:30:06 +00:00
else if ( sender = = BTN_RerollPID )
pkm . setPIDGender ( pkm . Gender ) ;
Implement PID-Ability corrections
Line 2211:
When the fields are loaded, if the user modifies the Ability on a <=Gen5
save file, if the ability is modified, the PID will be randomized to fit
the new PID.
When the Ability combobox is loaded, the personal entry may have 0 for
the ability2 (indicating same as ability1); if so, copy ability1 instead
of filtering it out.
When the Ability index is loaded, hidden ability is checked first, else
it tries to match: invalid, hidden (unflagged=illegal), if abilities
same use PIDAbility, else use the actual ability index.
2016-08-23 03:37:50 +00:00
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 ) ) ;
2016-07-30 05:30:06 +00:00
TB_PID . Text = pkm . PID . ToString ( "X8" ) ;
2014-12-14 20:15:53 +00:00
getQuickFiller ( dragout ) ;
2016-10-12 05:59:19 +00:00
if ( pkm . GenNumber < 6 & & SAV . Generation > = 6 )
2016-08-09 01:42:42 +00:00
TB_EC . Text = TB_PID . Text ;
2014-12-13 22:48:34 +00:00
}
private void updateRandomEC ( object sender , EventArgs e )
{
2017-02-27 16:59:20 +00:00
if ( pkm . Format < 6 )
return ;
2016-04-22 02:44:22 +00:00
2017-01-08 07:54:09 +00:00
int wIndex = Array . IndexOf ( Legal . WurmpleEvolutions , WinFormsUtil . getIndex ( CB_Species ) ) ;
2016-04-22 02:44:22 +00:00
if ( wIndex < 0 )
{
TB_EC . Text = Util . rnd32 ( ) . ToString ( "X8" ) ;
}
else
{
uint EC ;
2017-04-13 04:38:53 +00:00
bool valid ;
do
{
EC = Util . rnd32 ( ) ;
uint evoVal ;
switch ( pkm . GenNumber )
{
case 4 :
2017-05-04 06:14:34 +00:00
case 3 : evoVal = pkm . EncryptionConstant & 0xFFFF ; break ;
2017-04-13 04:38:53 +00:00
default : evoVal = pkm . EncryptionConstant > > 16 ; break ;
}
evoVal = evoVal % 10 / 5 ;
valid = evoVal = = wIndex / 2 ;
} while ( ! valid ) ;
2016-04-22 02:44:22 +00:00
TB_EC . Text = EC . ToString ( "X8" ) ;
}
2017-04-13 04:38:53 +00:00
updateLegality ( ) ;
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
}
2016-01-03 04:22:53 +00:00
private void updateHackedStatText ( object sender , EventArgs e )
{
2016-01-17 21:27:24 +00:00
if ( ! CHK_HackedStats . Checked | | ! ( sender is TextBox ) )
2016-01-03 04:22:53 +00:00
return ;
2016-01-17 21:27:24 +00:00
string text = ( ( TextBox ) sender ) . Text ;
2016-01-27 05:04:17 +00:00
if ( string . IsNullOrWhiteSpace ( text ) )
2016-01-17 21:27:24 +00:00
( ( TextBox ) sender ) . Text = "0" ;
2016-01-03 04:22:53 +00:00
if ( Convert . ToUInt32 ( text ) > ushort . MaxValue )
2016-01-17 21:27:24 +00:00
( ( TextBox ) sender ) . Text = "65535" ;
2016-01-03 04:22:53 +00:00
}
2014-12-13 22:48:34 +00:00
private void update255_MTB ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2016-07-18 18:51:26 +00:00
if ( Util . ToInt32 ( ( ( MaskedTextBox ) sender ) . Text ) > byte . MaxValue )
( ( MaskedTextBox ) sender ) . Text = "255" ;
2014-07-12 01:39:24 +00:00
}
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 ;
2016-12-17 04:30:06 +00:00
updateGender ( ) ;
2014-12-13 22:48:34 +00:00
updateStats ( ) ;
// Repopulate Abilities if Species Form has different abilities
2016-06-28 06:03:57 +00:00
setAbilityList ( ) ;
2014-12-13 22:48:34 +00:00
// Gender Forms
2017-01-08 07:54:09 +00:00
if ( WinFormsUtil . getIndex ( CB_Species ) = = 201 & & fieldsLoaded )
2016-07-28 01:20:15 +00:00
{
2016-10-22 17:38:33 +00:00
if ( SAV . Generation = = 3 )
2016-08-28 01:42:07 +00:00
{
pkm . setPIDUnown3 ( CB_Form . SelectedIndex ) ;
TB_PID . Text = pkm . PID . ToString ( "X8" ) ;
}
2016-10-22 17:38:33 +00:00
else if ( SAV . Generation = = 2 )
{
int desiredForm = CB_Form . SelectedIndex ;
while ( pkm . AltForm ! = desiredForm )
updateRandomIVs ( null , null ) ;
}
2016-07-28 01:20:15 +00:00
}
else if ( PKX . getGender ( CB_Form . Text ) < 2 )
2017-02-25 23:52:57 +00:00
{
if ( CB_Form . Items . Count = = 2 ) // actually M/F; Pumpkaboo formes in German are S,M,L,XL
Label_Gender . Text = gendersymbols [ PKX . getGender ( CB_Form . Text ) ] ;
}
2016-01-12 05:19:01 +00:00
if ( changingFields )
return ;
changingFields = true ;
2016-01-22 06:55:20 +00:00
MT_Form . Text = CB_Form . SelectedIndex . ToString ( ) ;
2016-01-12 05:19:01 +00:00
changingFields = false ;
2017-01-29 18:45:02 +00:00
if ( fieldsLoaded )
getQuickFiller ( dragout ) ;
2016-01-12 05:19:01 +00:00
}
private void updateHaXForm ( object sender , EventArgs e )
{
if ( changingFields )
return ;
changingFields = true ;
2016-07-21 03:40:03 +00:00
int form = pkm . AltForm = Util . ToInt32 ( MT_Form . Text ) ;
2016-01-12 05:19:01 +00:00
CB_Form . SelectedIndex = CB_Form . Items . Count > form ? form : - 1 ;
changingFields = false ;
2017-01-29 18:45:02 +00:00
if ( fieldsLoaded )
getQuickFiller ( dragout ) ;
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
{
2016-11-13 16:03:27 +00:00
ComboBox [ ] cbs = { CB_Move1 , CB_Move2 , CB_Move3 , CB_Move4 } ;
ComboBox [ ] pps = { CB_PPu1 , CB_PPu2 , CB_PPu3 , CB_PPu4 } ;
MaskedTextBox [ ] tbs = { TB_PP1 , TB_PP2 , TB_PP3 , TB_PP4 } ;
int index = Array . IndexOf ( cbs , sender ) ;
if ( index < 0 )
index = Array . IndexOf ( pps , sender ) ;
if ( index < 0 )
return ;
2017-01-08 07:54:09 +00:00
int move = WinFormsUtil . getIndex ( cbs [ index ] ) ;
2016-11-13 16:03:27 +00:00
int pp = pps [ index ] . SelectedIndex ;
if ( move = = 0 & & pp ! = 0 )
{
pps [ index ] . SelectedIndex = 0 ;
return ; // recursively triggers
}
tbs [ index ] . Text = pkm . getMovePP ( move , pp ) . 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 ( ) ;
2015-12-02 07:08:16 +00:00
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).
2016-01-05 06:42:38 +00:00
CB_PKRSDays . SelectedIndex = currentDuration < CB_PKRSDays . Items . Count ? currentDuration : 1 ;
2015-03-14 02:59:51 +00:00
2015-03-12 04:44:12 +00:00
if ( CB_PKRSStrain . SelectedIndex ! = 0 ) return ;
2015-03-14 02:59:51 +00:00
2015-03-12 04:44:12 +00:00
// Never Infected
2015-04-03 01:44:03 +00:00
CB_PKRSDays . SelectedIndex = 0 ;
2015-03-12 04:44:12 +00:00
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 )
2016-10-12 05:59:19 +00:00
CHK_Cured . Checked = CHK_Infected . Checked = false ; // No Strain = Never Cured / Infected, triggers Strain update
else CHK_Cured . Checked = true ; // Any Strain = Cured
2014-06-28 21:22:05 +00:00
}
2014-12-26 18:46:18 +00:00
private void updatePKRSCured ( object sender , EventArgs e )
{
2015-11-06 06:59:55 +00:00
if ( ! fieldsInitialized ) return ;
2014-12-26 18:46:18 +00:00
// 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 )
{
2015-11-06 06:59:55 +00:00
if ( ! fieldsInitialized ) return ;
2015-01-27 06:05:04 +00:00
if ( CHK_Cured . Checked & & ! CHK_Infected . Checked ) { CHK_Cured . Checked = false ; return ; }
2015-03-11 01:44:51 +00:00
if ( CHK_Cured . Checked ) return ;
2014-12-26 18:46:18 +00:00
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 ; }
2015-06-30 03:09:34 +00:00
else if ( CB_PKRSStrain . SelectedIndex = = 0 ) { CB_PKRSStrain . SelectedIndex = 1 ; Label_PKRSdays . Visible = CB_PKRSDays . Visible = true ; updatePKRSCured ( sender , e ) ; }
2014-12-26 18:46:18 +00:00
// if not cured yet, days > 0
2015-03-11 01:44:51 +00:00
if ( CHK_Infected . Checked & & CB_PKRSDays . SelectedIndex = = 0 ) CB_PKRSDays . SelectedIndex + + ;
2014-12-26 18:46:18 +00:00
}
2014-12-24 07:29:57 +00:00
private void updateCountry ( object sender , EventArgs e )
{
2017-01-08 07:54:09 +00:00
if ( WinFormsUtil . getIndex ( sender as ComboBox ) > 0 )
setCountrySubRegion ( CB_SubRegion , "sr_" + WinFormsUtil . getIndex ( sender as ComboBox ) . ToString ( "000" ) ) ;
2014-12-24 07:29:57 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateSpecies ( object sender , EventArgs e )
{
2016-10-12 05:59:19 +00:00
// Get Species dependent information
setAbilityList ( ) ;
2016-06-30 05:58:02 +00:00
setForms ( ) ;
2016-10-12 05:59:19 +00:00
updateForm ( null , null ) ;
if ( ! fieldsLoaded )
return ;
2014-12-13 22:48:34 +00:00
2017-01-08 07:54:09 +00:00
pkm . Species = WinFormsUtil . getIndex ( CB_Species ) ;
2014-12-13 22:48:34 +00:00
// Recalculate EXP for Given Level
2016-10-12 05:59:19 +00:00
uint EXP = PKX . getEXP ( pkm . CurrentLevel , pkm . Species ) ;
2015-09-25 02:54:50 +00:00
TB_EXP . Text = EXP . ToString ( ) ;
2014-12-13 22:48:34 +00:00
// Check for Gender Changes
2016-12-17 04:30:06 +00:00
updateGender ( ) ;
2014-12-13 22:48:34 +00:00
// If species changes and no nickname, set the new name == speciesName.
if ( ! CHK_Nicknamed . Checked )
updateNickname ( sender , e ) ;
2016-02-17 15:54:59 +00:00
2016-02-28 02:10:02 +00:00
updateLegality ( ) ;
2014-12-13 22:48:34 +00:00
}
2016-08-27 20:05:01 +00:00
private void updateOriginGame ( object sender , EventArgs e )
{
2017-01-08 07:54:09 +00:00
GameVersion Version = ( GameVersion ) WinFormsUtil . getIndex ( CB_GameOrigin ) ;
2016-08-27 20:05:01 +00:00
// check if differs
2016-10-29 22:41:55 +00:00
GameVersion newTrack = GameUtil . getMetLocationVersionGroup ( Version ) ;
2016-08-27 20:05:01 +00:00
if ( newTrack ! = origintrack )
2014-12-24 07:29:57 +00:00
{
2016-10-29 22:41:55 +00:00
var met_list = GameInfo . getLocationList ( Version , SAV . Generation , egg : false ) ;
2016-08-27 20:05:01 +00:00
CB_MetLocation . DisplayMember = "Text" ;
CB_MetLocation . ValueMember = "Value" ;
CB_MetLocation . DataSource = new BindingSource ( met_list , null ) ;
2017-01-26 06:51:52 +00:00
int metLoc = 0 ; // transporter or pal park for past gen pkm
switch ( newTrack )
{
case GameVersion . GO : metLoc = 30012 ; break ;
case GameVersion . RBY : metLoc = 30013 ; break ;
}
if ( metLoc ! = 0 )
CB_MetLocation . SelectedValue = metLoc ;
else
CB_MetLocation . SelectedIndex = metLoc ;
2014-12-13 22:48:34 +00:00
2016-10-29 22:41:55 +00:00
var egg_list = GameInfo . getLocationList ( Version , SAV . Generation , egg : true ) ;
2014-12-13 22:48:34 +00:00
CB_EggLocation . DisplayMember = "Text" ;
CB_EggLocation . ValueMember = "Value" ;
2016-08-27 20:05:01 +00:00
CB_EggLocation . DataSource = new BindingSource ( egg_list , null ) ;
CB_EggLocation . SelectedIndex = CHK_AsEgg . Checked ? 1 : 0 ; // daycare : none
origintrack = newTrack ;
2016-10-02 04:43:23 +00:00
// 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
}
2014-12-17 02:56:08 +00:00
2014-12-24 07:29:57 +00:00
// Visibility logic for Gen 4 encounter type; only show for Gen 4 Pokemon.
2016-07-17 04:31:49 +00:00
if ( SAV . Generation > = 4 )
{
2016-08-28 19:42:29 +00:00
bool g4 = Version > = GameVersion . HG & & Version < = GameVersion . Pt ;
2016-08-27 20:05:01 +00:00
if ( ( int ) Version = = 9 ) // invalid
g4 = false ;
2016-11-11 16:04:40 +00:00
CB_EncounterType . Visible = Label_EncounterType . Visible = g4 & & SAV . Generation < 7 ;
2016-07-17 04:31:49 +00:00
if ( ! g4 )
CB_EncounterType . SelectedValue = 0 ;
}
2014-12-24 07:29:57 +00:00
2016-02-27 04:33:18 +00:00
if ( ! fieldsLoaded )
return ;
2016-08-27 20:05:01 +00:00
pkm . Version = ( int ) Version ;
2016-11-13 06:09:40 +00:00
setMarkings ( ) ; // Set/Remove KB marking
2016-02-28 02:10:02 +00:00
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
{
2016-06-20 04:22:43 +00:00
if ( CB_ExtraBytes . Items . Count = = 0 )
return ;
2014-12-13 22:48:34 +00:00
// Changed Extra Byte's Value
2016-07-18 18:51:26 +00:00
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 ) ;
2016-06-20 04:22:43 +00:00
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
{
2016-06-20 04:22:43 +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.
2016-06-20 04:22:43 +00:00
TB_ExtraByte . Text = pkm . Data [ Convert . ToInt32 ( CB_ExtraBytes . Text , 16 ) ] . ToString ( ) ;
2014-06-28 21:22:05 +00:00
}
2015-09-21 03:34:09 +00:00
private void updateNatureModification ( object sender , EventArgs e )
{
2016-01-31 07:03:43 +00:00
if ( sender ! = CB_Nature ) return ;
2017-01-08 07:54:09 +00:00
int nature = WinFormsUtil . getIndex ( CB_Nature ) ;
2015-09-21 03:34:09 +00:00
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 )
2016-09-06 06:13:46 +00:00
label . ResetForeColor ( ) ;
2015-09-21 03:34:09 +00:00
// Set Colored StatLabels only if Nature isn't Neutral
NatureTip . SetToolTip ( CB_Nature ,
incr ! = decr
2016-01-17 21:27:24 +00:00
? $"+{labarray[incr].Text} / -{labarray[decr].Text}" . Replace ( ":" , "" )
2015-09-21 03:34:09 +00:00
: "-/-" ) ;
}
2014-12-13 22:48:34 +00:00
private void updateNickname ( object sender , EventArgs e )
2014-08-15 22:28:33 +00:00
{
2016-01-15 05:05:05 +00:00
if ( fieldsInitialized & & ModifierKeys = = Keys . Control & & sender ! = null ) // Import Showdown
2016-10-29 22:41:55 +00:00
{ clickShowdownImportPKM ( sender , e ) ; return ; }
2016-01-15 05:05:05 +00:00
if ( fieldsInitialized & & ModifierKeys = = Keys . Alt & & sender ! = null ) // Export Showdown
2016-10-29 22:41:55 +00:00
{ clickShowdownExportPKM ( sender , e ) ; return ; }
2016-11-13 15:38:41 +00:00
2017-02-04 05:48:43 +00:00
int lang = WinFormsUtil . getIndex ( CB_Language ) ;
2016-11-13 15:38:41 +00:00
2016-06-26 21:23:41 +00:00
if ( ! fieldsInitialized | | CHK_Nicknamed . Checked )
return ;
2015-03-11 01:44:51 +00:00
// Fetch Current Species and set it as Nickname Text
2017-01-08 07:54:09 +00:00
int species = WinFormsUtil . getIndex ( CB_Species ) ;
2016-06-26 21:23:41 +00:00
if ( species < 1 | | species > SAV . MaxSpeciesID )
2017-02-04 05:48:43 +00:00
{ TB_Nickname . Text = "" ; return ; }
if ( CHK_IsEgg . Checked )
species = 0 ; // get the egg name.
// If name is that of another language, don't replace the nickname
2017-02-12 17:59:49 +00:00
if ( sender ! = CB_Language & & species ! = 0 & & ! PKX . getIsNicknamedAnyLanguage ( species , TB_Nickname . Text , SAV . Generation ) )
2017-02-04 05:48:43 +00:00
return ;
TB_Nickname . Text = PKX . getSpeciesNameGeneration ( species , lang , SAV . Generation ) ;
if ( SAV . Generation = = 1 )
( ( PK1 ) pkm ) . setNotNicknamed ( ) ;
if ( SAV . Generation = = 2 )
( ( PK2 ) pkm ) . setNotNicknamed ( ) ;
2014-08-15 22:28:33 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateNicknameClick ( object sender , MouseEventArgs e )
2014-08-15 22:28:33 +00:00
{
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
2016-01-31 07:03:43 +00:00
if ( ModifierKeys ! = Keys . Control )
return ;
2017-04-09 21:06:50 +00:00
if ( tb = = TB_Nickname )
{
pkm . Nickname = tb . Text ;
var d = new f2_Text ( tb , pkm . Nickname_Trash ) ;
d . ShowDialog ( ) ;
tb . Text = d . FinalString ;
pkm . Nickname_Trash = d . FinalBytes ;
}
else if ( tb = = TB_OT )
{
pkm . OT_Name = tb . Text ;
var d = new f2_Text ( tb , pkm . OT_Trash ) ;
d . ShowDialog ( ) ;
tb . Text = d . FinalString ;
pkm . OT_Trash = d . FinalBytes ;
}
else if ( tb = = TB_OTt2 )
{
pkm . HT_Name = tb . Text ;
var d = new f2_Text ( tb , pkm . HT_Trash ) ;
d . ShowDialog ( ) ;
tb . Text = d . FinalString ;
pkm . HT_Trash = d . FinalBytes ;
}
2014-08-15 22:28:33 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateNotOT ( object sender , EventArgs e )
2014-08-31 20:32:04 +00:00
{
2016-02-03 04:05:46 +00:00
if ( string . IsNullOrWhiteSpace ( TB_OTt2 . Text ) )
2014-08-31 20:32:04 +00:00
{
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 = "" ;
2016-06-20 04:22:43 +00:00
TB_Friendship . Text = pkm . CurrentFriendship . ToString ( ) ;
2014-08-31 20:32:04 +00:00
}
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-08-31 20:32:04 +00:00
}
2014-12-13 22:48:34 +00:00
private void updateIsEgg ( object sender , EventArgs e )
{
2016-10-12 05:59:19 +00:00
// Display hatch counter if it is an egg, Display Friendship if it is not.
Label_HatchCounter . Visible = CHK_IsEgg . Checked & & SAV . Generation > 1 ;
Label_Friendship . Visible = ! CHK_IsEgg . Checked & & SAV . Generation > 1 ;
if ( ! fieldsLoaded )
return ;
pkm . IsEgg = CHK_IsEgg . Checked ;
2014-12-13 22:48:34 +00:00
if ( CHK_IsEgg . Checked )
2014-06-28 21:22:05 +00:00
{
2014-12-13 22:48:34 +00:00
TB_Friendship . Text = "1" ;
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 ) ;
2016-10-12 05:59:19 +00:00
// if egg wasn't originally obtained by OT => Link Trade, else => None
bool isTraded = SAV . OT ! = TB_OT . Text | | SAV . TID ! = Util . ToInt32 ( TB_TID . Text ) | | SAV . SID ! = Util . ToInt32 ( TB_SID . Text ) ;
CB_MetLocation . SelectedIndex = isTraded ? 2 : 0 ;
if ( ! CHK_Nicknamed . Checked )
{
2017-02-05 02:27:28 +00:00
TB_Nickname . Text = PKX . getSpeciesNameGeneration ( 0 , WinFormsUtil . getIndex ( CB_Language ) , pkm . Format ) ;
2016-10-12 05:59:19 +00:00
CHK_Nicknamed . Checked = true ;
}
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 ) ;
2017-01-08 07:54:09 +00:00
TB_Friendship . Text = SAV . Personal [ WinFormsUtil . getIndex ( CB_Species ) ] . BaseFriendship . ToString ( ) ;
2015-01-01 19:38:37 +00:00
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
}
2016-08-29 05:21:55 +00:00
2017-02-05 02:27:28 +00:00
if ( TB_Nickname . Text = = PKX . getSpeciesNameGeneration ( 0 , WinFormsUtil . getIndex ( CB_Language ) , pkm . Format ) )
2016-10-12 05:59:19 +00:00
CHK_Nicknamed . Checked = false ;
}
2014-12-20 19:27:29 +00:00
2015-03-11 01:44:51 +00:00
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 ;
2016-09-21 02:21:58 +00:00
if ( CHK_AsEgg . Checked )
{
if ( ! fieldsLoaded )
return ;
CAL_EggDate . Value = DateTime . Now ;
CB_EggLocation . SelectedIndex = 1 ;
return ;
}
2015-03-11 01:44:51 +00:00
// Remove egg met data
CHK_IsEgg . Checked = false ;
CAL_EggDate . Value = new DateTime ( 2000 , 01 , 01 ) ;
CB_EggLocation . SelectedValue = 0 ;
2016-02-17 15:54:59 +00:00
2016-02-28 02:10:02 +00:00
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 ) ;
2017-01-08 07:54:09 +00:00
pkm . Nature = WinFormsUtil . getIndex ( CB_Nature ) ;
2016-07-29 05:33:16 +00:00
pkm . Gender = PKX . getGender ( Label_Gender . Text ) ;
pkm . AltForm = CB_Form . SelectedIndex ;
2017-01-08 07:54:09 +00:00
pkm . Version = WinFormsUtil . getIndex ( CB_GameOrigin ) ;
2014-11-15 05:08:00 +00:00
2016-09-02 21:20:39 +00:00
if ( pkm . Format > 2 )
pkm . setShinyPID ( ) ;
else
{
2017-01-25 05:28:29 +00:00
// IVs determine shininess
// All 10IV except for one where (IV & 2 == 2) [gen specific]
int [ ] and2 = { 2 , 3 , 6 , 7 , 10 , 11 , 14 , 15 } ;
int randIV = and2 [ Util . rnd32 ( ) % and2 . Length ] ;
if ( pkm . Format = = 1 )
{
TB_ATKIV . Text = "10" ; // an attempt was made
TB_DEFIV . Text = randIV . ToString ( ) ;
}
else // pkm.Format == 2
{
TB_ATKIV . Text = randIV . ToString ( ) ;
TB_DEFIV . Text = "10" ;
}
2016-09-02 21:20:39 +00:00
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
2014-12-14 20:15:53 +00:00
getQuickFiller ( dragout ) ;
2016-07-29 05:33:16 +00:00
updateLegality ( ) ;
2014-11-15 05:08:00 +00:00
}
2015-09-21 03:34:09 +00:00
private void updateTSV ( object sender , EventArgs e )
{
2016-06-21 04:11:48 +00:00
if ( SAV . Generation < 6 )
return ;
2016-07-18 06:40:40 +00:00
2016-11-08 16:43:57 +00:00
var TSV = pkm . TSV . ToString ( "0000" ) ;
string IDstr = "TSV: " + TSV ;
if ( SAV . Generation > 6 )
IDstr + = Environment . NewLine + "G7TID: " + pkm . TrainerID7 . ToString ( "000000" ) ;
Tip1 . SetToolTip ( TB_TID , IDstr ) ;
Tip2 . SetToolTip ( TB_SID , IDstr ) ;
2015-09-21 03:34:09 +00:00
2016-07-18 06:40:40 +00:00
pkm . PID = Util . getHEXval ( TB_PID . Text ) ;
var PSV = pkm . PSV ;
2015-09-25 02:54:50 +00:00
Tip3 . SetToolTip ( TB_PID , "PSV: " + PSV . ToString ( "0000" ) ) ;
2015-09-21 03:34:09 +00:00
}
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
2016-01-09 20:39:18 +00:00
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
2015-02-26 04:19:43 +00:00
// Max TID/SID is 65535
2016-01-03 04:22:53 +00:00
if ( Util . ToUInt32 ( TB_TID . Text ) > ushort . MaxValue ) TB_TID . Text = "65535" ;
if ( Util . ToUInt32 ( TB_SID . Text ) > ushort . MaxValue ) TB_SID . Text = "65535" ;
2015-01-01 19:38:37 +00:00
2016-07-19 03:25:54 +00:00
setIsShiny ( sender ) ;
2015-02-28 05:51:19 +00:00
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
2016-07-30 05:30:06 +00:00
if ( SAV . Generation < = 4 & & fieldsLoaded )
2016-06-20 04:22:43 +00:00
{
2016-07-30 05:30:06 +00:00
fieldsLoaded = false ;
2016-06-20 04:22:43 +00:00
pkm . PID = Util . getHEXval ( TB_PID . Text ) ;
CB_Nature . SelectedValue = pkm . Nature ;
2016-07-30 05:30:06 +00:00
Label_Gender . Text = gendersymbols [ pkm . Gender ] ;
Label_Gender . ForeColor = pkm . Gender = = 2 ? Label_Species . ForeColor : ( pkm . Gender = = 1 ? Color . Red : Color . Blue ) ;
fieldsLoaded = true ;
2016-06-20 04:22:43 +00:00
}
2014-12-13 22:48:34 +00:00
}
2016-10-01 23:52:29 +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 ;
2017-04-02 15:10:40 +00:00
CHK_Shadow . Checked = NUD_Purification . Value > 0 ;
2016-10-01 23:52:29 +00:00
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 ;
}
2016-02-28 02:10:02 +00:00
private void validateComboBox ( object sender )
2014-12-13 22:48:34 +00:00
{
2016-03-12 04:57:55 +00:00
if ( ! formInitialized )
return ;
2016-03-06 22:42:20 +00:00
ComboBox cb = sender as ComboBox ;
if ( cb = = null )
2016-02-01 07:15:54 +00:00
return ;
2016-03-06 22:42:20 +00:00
2017-03-26 16:24:02 +00:00
if ( cb . Text = = "" & & cb . Items . Count > 0 )
2016-03-06 00:59:16 +00:00
{ cb . SelectedIndex = 0 ; return ; }
2016-09-06 06:13:46 +00:00
if ( cb . SelectedValue = = null )
cb . BackColor = Color . DarkSalmon ;
else
cb . ResetBackColor ( ) ;
2016-02-28 02:10:02 +00:00
}
2016-09-05 21:26:21 +00:00
private void validateComboBox ( object sender , System . ComponentModel . CancelEventArgs e )
2016-02-28 02:10:02 +00:00
{
if ( ! ( sender is ComboBox ) )
return ;
2014-12-14 20:15:53 +00:00
2016-02-28 02:10:02 +00:00
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 )
{
2016-08-13 01:29:31 +00:00
if ( ! fieldsInitialized )
return ;
2016-09-05 21:26:21 +00:00
validateComboBox ( sender , null ) ;
Implement PID-Ability corrections
Line 2211:
When the fields are loaded, if the user modifies the Ability on a <=Gen5
save file, if the ability is modified, the PID will be randomized to fit
the new PID.
When the Ability combobox is loaded, the personal entry may have 0 for
the ability2 (indicating same as ability1); if so, copy ability1 instead
of filtering it out.
When the Ability index is loaded, hidden ability is checked first, else
it tries to match: invalid, hidden (unflagged=illegal), if abilities
same use PIDAbility, else use the actual ability index.
2016-08-23 03:37:50 +00:00
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 )
2016-10-12 05:59:19 +00:00
{
pkm . Nature = CB_Nature . SelectedIndex ;
Implement PID-Ability corrections
Line 2211:
When the fields are loaded, if the user modifies the Ability on a <=Gen5
save file, if the ability is modified, the PID will be randomized to fit
the new PID.
When the Ability combobox is loaded, the personal entry may have 0 for
the ability2 (indicating same as ability1); if so, copy ability1 instead
of filtering it out.
When the Ability index is loaded, hidden ability is checked first, else
it tries to match: invalid, hidden (unflagged=illegal), if abilities
same use PIDAbility, else use the actual ability index.
2016-08-23 03:37:50 +00:00
updateRandomPID ( sender , e ) ;
2016-10-12 05:59:19 +00:00
}
2017-04-10 22:59:16 +00:00
if ( sender = = CB_HeldItem | | sender = = CB_Ability )
2017-02-26 15:55:22 +00:00
updateLegality ( ) ;
Implement PID-Ability corrections
Line 2211:
When the fields are loaded, if the user modifies the Ability on a <=Gen5
save file, if the ability is modified, the PID will be randomized to fit
the new PID.
When the Ability combobox is loaded, the personal entry may have 0 for
the ability2 (indicating same as ability1); if so, copy ability1 instead
of filtering it out.
When the Ability index is loaded, hidden ability is checked first, else
it tries to match: invalid, hidden (unflagged=illegal), if abilities
same use PIDAbility, else use the actual ability index.
2016-08-23 03:37:50 +00:00
}
2015-09-21 03:34:09 +00:00
updateNatureModification ( sender , null ) ;
2014-12-13 22:48:34 +00:00
updateIVs ( null , null ) ; // updating Nature will trigger stats to update as well
}
2016-02-17 15:54:59 +00:00
private void validateMove ( object sender , EventArgs e )
{
2016-08-13 01:29:31 +00:00
if ( ! fieldsInitialized )
return ;
2016-03-06 22:42:20 +00:00
validateComboBox ( sender ) ;
2016-02-24 03:19:25 +00:00
if ( ! fieldsLoaded )
return ;
2016-02-17 15:54:59 +00:00
2016-02-24 03:19:25 +00:00
if ( new [ ] { CB_Move1 , CB_Move2 , CB_Move3 , CB_Move4 } . Contains ( sender ) ) // Move
2016-02-17 15:54:59 +00:00
updatePP ( sender , e ) ;
2016-08-27 15:56:50 +00:00
// Legality
2017-01-08 07:54:09 +00:00
pkm . Moves = new [ ] { CB_Move1 , CB_Move2 , CB_Move3 , CB_Move4 } . Select ( WinFormsUtil . getIndex ) . ToArray ( ) ;
pkm . RelearnMoves = new [ ] { CB_RelearnMove1 , CB_RelearnMove2 , CB_RelearnMove3 , CB_RelearnMove4 } . Select ( WinFormsUtil . getIndex ) . ToArray ( ) ;
2016-11-16 06:01:28 +00:00
updateLegality ( skipMoveRepop : true ) ;
}
private void validateMovePaint ( object sender , DrawItemEventArgs e )
{
if ( e . Index < 0 ) return ;
var i = ( ComboItem ) ( sender as ComboBox ) . Items [ e . Index ] ;
var moves = Legality . AllSuggestedMovesAndRelearn ;
bool vm = moves ! = null & & moves . Contains ( i . Value ) & & ! HaX ;
bool current = ( e . State & DrawItemState . Selected ) = = DrawItemState . Selected ;
Brush tBrush = current ? SystemBrushes . HighlightText : new SolidBrush ( e . ForeColor ) ;
Brush brush = current ? SystemBrushes . Highlight : vm ? Brushes . PaleGreen : new SolidBrush ( e . BackColor ) ;
e . Graphics . FillRectangle ( brush , e . Bounds ) ;
e . Graphics . DrawString ( i . Text , e . Font , tBrush , e . Bounds , StringFormat . GenericDefault ) ;
if ( current ) return ;
tBrush . Dispose ( ) ;
if ( ! vm )
brush . Dispose ( ) ;
2016-02-17 15:54:59 +00:00
}
2016-02-28 02:10:02 +00:00
private void validateLocation ( object sender , EventArgs e )
{
validateComboBox ( sender ) ;
if ( ! fieldsLoaded )
return ;
2017-01-08 07:54:09 +00:00
pkm . Met_Location = WinFormsUtil . getIndex ( CB_MetLocation ) ;
pkm . Egg_Location = WinFormsUtil . getIndex ( CB_EggLocation ) ;
2016-02-28 02:10:02 +00:00
updateLegality ( ) ;
}
2014-12-13 22:48:34 +00:00
private void removedropCB ( object sender , KeyEventArgs e )
{
( ( ComboBox ) sender ) . DroppedDown = false ;
}
2016-11-17 05:16:44 +00:00
private void showLegality ( PKM pk , bool tabs , bool verbose , bool skipMoveRepop = false )
2016-03-09 03:20:26 +00:00
{
LegalityAnalysis la = new LegalityAnalysis ( pk ) ;
2016-11-14 00:24:15 +00:00
if ( ! la . Parsed )
2016-10-23 19:48:49 +00:00
{
2017-02-13 01:00:03 +00:00
WinFormsUtil . Alert ( pk . Format < 3
? $"Checking legality of PK{pk.Format} files is not supported."
: $"Checking legality of PK{pk.Format} files that originated from Gen{pk.GenNumber} is not supported." ) ;
2016-10-23 19:48:49 +00:00
return ;
}
2016-03-14 01:09:12 +00:00
if ( tabs )
2016-11-17 05:16:44 +00:00
updateLegality ( la , skipMoveRepop ) ;
2017-03-21 07:18:38 +00:00
WinFormsUtil . Alert ( la . Report ( verbose ) ) ;
2016-03-09 03:20:26 +00:00
}
2016-11-16 06:01:28 +00:00
private void updateLegality ( LegalityAnalysis la = null , bool skipMoveRepop = false )
2016-02-17 15:54:59 +00:00
{
2017-02-13 01:00:03 +00:00
if ( ! fieldsLoaded )
return ;
Legality = la ? ? new LegalityAnalysis ( pkm ) ;
if ( ! Legality . Parsed | | HaX )
2016-10-23 19:48:49 +00:00
{
2017-02-13 01:00:03 +00:00
PB_Legal . Visible =
PB_WarnMove1 . Visible = PB_WarnMove2 . Visible = PB_WarnMove3 . Visible = PB_WarnMove4 . Visible =
PB_WarnRelearn1 . Visible = PB_WarnRelearn2 . Visible = PB_WarnRelearn3 . Visible = PB_WarnRelearn4 . Visible = false ;
return ;
}
2016-02-17 15:54:59 +00:00
2017-02-13 01:00:03 +00:00
PB_Legal . Visible = true ;
PB_Legal . Image = Legality . Valid ? Resources . valid : Resources . warn ;
2016-11-16 06:01:28 +00:00
2017-02-13 01:00:03 +00:00
// Refresh Move Legality
for ( int i = 0 ; i < 4 ; i + + )
2017-03-20 07:03:31 +00:00
movePB [ i ] . Visible = ! Legality . vMoves [ i ] . Valid ;
2017-02-13 01:00:03 +00:00
2017-03-26 02:57:38 +00:00
if ( pkm . Format > = 6 )
2017-02-13 01:00:03 +00:00
for ( int i = 0 ; i < 4 ; i + + )
2017-03-26 02:57:38 +00:00
relearnPB [ i ] . Visible = ! Legality . vRelearn [ i ] . Valid ;
2017-02-01 02:48:33 +00:00
2017-02-13 01:00:03 +00:00
if ( skipMoveRepop )
return ;
// Resort moves
bool tmp = fieldsLoaded ;
fieldsLoaded = false ;
var cb = new [ ] { CB_Move1 , CB_Move2 , CB_Move3 , CB_Move4 } ;
var moves = Legality . AllSuggestedMovesAndRelearn ;
2017-03-30 05:23:18 +00:00
var moveList = GameInfo . MoveDataSource . OrderByDescending ( m = > moves . Contains ( m . Value ) ) . ToArray ( ) ;
2017-02-13 01:00:03 +00:00
foreach ( ComboBox c in cb )
2016-11-16 06:01:28 +00:00
{
2017-02-13 01:00:03 +00:00
var index = WinFormsUtil . getIndex ( c ) ;
c . DataSource = new BindingSource ( moveList , null ) ;
c . SelectedValue = index ;
2017-03-30 05:23:18 +00:00
if ( c . Visible )
c . SelectionLength = 0 ; // flicker hack
2016-11-16 06:01:28 +00:00
}
2017-02-13 01:00:03 +00:00
fieldsLoaded | = tmp ;
2016-02-17 15:54:59 +00:00
}
2016-12-17 04:30:06 +00:00
private void updateGender ( )
{
2017-02-25 23:52:57 +00:00
int cg = PKX . getGender ( Label_Gender . Text ) ;
2017-01-08 07:54:09 +00:00
int gt = SAV . Personal . getFormeEntry ( WinFormsUtil . getIndex ( CB_Species ) , CB_Form . SelectedIndex ) . Gender ;
2016-12-17 04:30:06 +00:00
int Gender ;
if ( gt = = 255 ) // Genderless
Gender = 2 ;
else if ( gt = = 254 ) // Female Only
Gender = 1 ;
else if ( gt = = 0 ) // Male Only
Gender = 0 ;
2017-01-08 07:54:09 +00:00
else if ( cg = = 2 | | WinFormsUtil . getIndex ( CB_GameOrigin ) < 24 )
2016-12-17 04:30:06 +00:00
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 ) ;
}
2014-12-13 22:48:34 +00:00
private void updateStats ( )
{
// Generate the stats.
2016-10-12 05:59:19 +00:00
pkm . setStats ( pkm . getStats ( SAV . Personal . getFormeEntry ( pkm . Species , pkm . AltForm ) ) ) ;
2014-06-28 21:22:05 +00:00
2016-10-12 05:59:19 +00:00
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 ( ) ;
2014-06-28 21:22:05 +00:00
2014-12-13 22:48:34 +00:00
// Recolor the Stat Labels based on boosted stats.
{
2016-07-21 03:40:03 +00:00
int incr = pkm . Nature / 5 ;
int decr = pkm . Nature % 5 ;
2014-06-28 21:22:05 +00:00
2015-03-11 01:44:51 +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 )
2016-09-06 06:13:46 +00:00
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
2015-03-11 01:44:51 +00:00
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
}
2016-01-30 01:27:20 +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 = "☆" ;
2017-01-08 07:54:09 +00:00
TB_Nickname . Font = TB_OT . Font = TB_OTt2 . Font = FontUtil . getPKXFont ( 11 ) ;
2016-01-30 01:27:20 +00:00
}
// 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
2014-12-24 07:29:57 +00:00
private void openRibbons ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2016-07-17 00:19:26 +00:00
new RibbonEditor ( ) . ShowDialog ( ) ;
}
private void openMedals ( object sender , EventArgs e )
{
new SuperTrainingEditor ( ) . ShowDialog ( ) ;
2014-06-28 21:22:05 +00:00
}
2014-12-24 07:29:57 +00:00
private void openHistory ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2015-09-29 04:11:03 +00:00
// Write back current values
2016-10-20 01:19:01 +00:00
pkm . HT_Name = TB_OTt2 . Text ;
pkm . OT_Name = TB_OT . Text ;
pkm . IsEgg = CHK_IsEgg . Checked ;
pkm . CurrentFriendship = Util . ToInt32 ( TB_Friendship . Text ) ;
2015-09-29 04:11:03 +00:00
new MemoryAmie ( ) . ShowDialog ( ) ;
2016-10-20 01:19:01 +00:00
TB_Friendship . Text = pkm . CurrentFriendship . ToString ( ) ;
2014-06-28 21:22:05 +00:00
}
2014-12-22 04:07:04 +00:00
// Open/Save Array Manipulation //
2016-06-21 06:02:26 +00:00
public bool verifiedPKM ( )
2014-06-28 21:22:05 +00:00
{
2014-11-29 19:07:01 +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
2014-07-16 19:16:16 +00:00
CB_RelearnMove1 , CB_RelearnMove2 , CB_RelearnMove3 , CB_RelearnMove4 // Moves
2014-06-28 21:22:05 +00:00
} ;
2016-09-06 06:13:46 +00:00
2017-03-30 00:43:17 +00:00
ComboBox cb = cba . FirstOrDefault ( c = > c . BackColor = = Color . DarkSalmon & & c . Items . Count ! = 0 ) ;
2016-09-06 06:13:46 +00:00
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
}
2016-09-06 06:13:46 +00:00
else if ( SAV . Generation > = 3 & & Convert . ToUInt32 ( TB_EVTotal . Text ) > 510 & & ! CHK_HackedStats . Checked )
tabMain . SelectedTab = Tab_Stats ;
2017-01-08 07:54:09 +00:00
else if ( WinFormsUtil . getIndex ( CB_Species ) = = 0 )
2016-09-06 06:13:46 +00:00
tabMain . SelectedTab = Tab_Main ;
else
return true ;
SystemSounds . Exclamation . Play ( ) ;
return false ;
2014-06-28 21:22:05 +00:00
}
2016-06-20 04:22:43 +00:00
public PKM preparePKM ( bool click = true )
2014-06-28 21:22:05 +00:00
{
2014-12-14 20:15:53 +00:00
if ( click )
2017-03-13 00:01:48 +00:00
ValidateChildren ( ) ;
2016-07-09 21:01:31 +00:00
PKM pk = getPKMfromFields ( ) ;
2016-06-22 05:19:26 +00:00
return pk ? . Clone ( ) ;
2016-06-20 04:22:43 +00:00
}
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 )
{
2016-08-12 03:02:13 +00:00
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 ] ) ;
2016-08-21 07:17:45 +00:00
e . Effect = DragDropEffects . Copy ;
2016-08-26 01:50:51 +00:00
Cursor = DefaultCursor ;
2014-06-28 21:22:05 +00:00
}
// Decrypted Export
private void dragout_MouseDown ( object sender , MouseEventArgs e )
{
2016-03-12 02:40:08 +00:00
if ( e . Button = = MouseButtons . Left & & ( ModifierKeys = = Keys . Alt | | ModifierKeys = = Keys . Shift ) )
clickQR ( sender , e ) ;
2016-03-09 03:20:26 +00:00
if ( e . Button = = MouseButtons . Right )
return ;
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) )
2016-03-09 03:20:26 +00:00
return ;
2014-06-28 21:22:05 +00:00
2016-03-09 03:20:26 +00:00
// Create Temp File to Drag
2016-06-20 04:22:43 +00:00
PKM pkx = preparePKM ( ) ;
2016-03-09 03:20:26 +00:00
bool encrypt = ModifierKeys = = Keys . Control ;
2016-12-03 04:05:11 +00:00
string fn = pkx . FileName ; fn = fn . Substring ( 0 , fn . LastIndexOf ( '.' ) ) ;
string filename = $"{fn}{(encrypt ? " . ek " + pkx.Format : " . " + pkx.Extension)}" ;
2016-03-09 03:20:26 +00:00
byte [ ] dragdata = encrypt ? pkx . EncryptedBoxData : pkx . DecryptedBoxData ;
// Make file
string newfile = Path . Combine ( Path . GetTempPath ( ) , Util . CleanFileName ( filename ) ) ;
try
{
File . WriteAllBytes ( newfile , dragdata ) ;
2016-08-21 07:17:45 +00:00
PictureBox pb = ( PictureBox ) sender ;
2017-02-05 07:11:48 +00:00
DragInfo . Cursor = Cursor = new Cursor ( ( ( Bitmap ) pb . Image ) . GetHicon ( ) ) ;
2016-03-09 03:20:26 +00:00
DoDragDrop ( new DataObject ( DataFormats . FileDrop , new [ ] { newfile } ) , DragDropEffects . Move ) ;
2014-06-28 21:22:05 +00:00
}
2016-03-09 03:20:26 +00:00
catch ( Exception x )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Error ( "Drag & Drop Error" , x ) ; }
2017-02-05 07:11:48 +00:00
DragInfo . Cursor = Cursor = DefaultCursor ;
2016-03-09 03:20:26 +00:00
File . Delete ( newfile ) ;
2014-06-28 21:22:05 +00:00
}
2014-12-14 20:15:53 +00:00
private void dragout_DragOver ( object sender , DragEventArgs e )
2014-06-28 21:22:05 +00:00
{
e . Effect = DragDropEffects . Move ;
}
2014-12-14 20:15:53 +00:00
// Dragout Display
2017-04-14 06:05:19 +00:00
private void dragoutEnter ( object sender , EventArgs e )
2014-06-28 21:22:05 +00:00
{
2017-01-14 21:10:36 +00:00
dragout . BackgroundImage = WinFormsUtil . getIndex ( CB_Species ) > 0 ? Resources . slotSet : Resources . slotDel ;
2017-04-14 06:05:19 +00:00
Cursor = Cursors . Hand ;
2014-06-28 21:22:05 +00:00
}
private void dragoutLeave ( object sender , EventArgs e )
{
2017-01-14 21:10:36 +00:00
dragout . BackgroundImage = Resources . slotTrans ;
2017-04-14 06:05:19 +00:00
if ( Cursor = = Cursors . Hand )
Cursor = Cursors . Default ;
2014-12-14 20:15:53 +00:00
}
private void dragoutDrop ( object sender , DragEventArgs e )
{
2016-08-21 07:17:45 +00:00
string [ ] files = ( string [ ] ) e . Data . GetData ( DataFormats . FileDrop ) ;
openQuick ( files [ 0 ] ) ;
e . Effect = DragDropEffects . Copy ;
2016-08-26 01:50:51 +00:00
Cursor = DefaultCursor ;
2014-06-28 21:22:05 +00:00
}
2016-10-18 17:44:36 +00:00
private void Main_FormClosing ( object sender , FormClosingEventArgs e )
{
2017-03-22 06:25:13 +00:00
if ( ( SAV . Edited | | PKMIsUnsaved ) & & DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Any unsaved changes will be lost." , "Are you sure you want to close PKHeX?" ) )
2017-02-08 05:12:18 +00:00
{
2017-02-08 05:13:33 +00:00
e . Cancel = true ;
return ;
2017-02-08 05:12:18 +00:00
}
2017-01-31 01:49:28 +00:00
try { Properties . Settings . Default . Save ( ) ; }
2017-02-08 05:13:33 +00:00
catch ( Exception x ) { File . WriteAllLines ( "config error.txt" , new [ ] { x . ToString ( ) } ) ; }
2016-10-18 17:44:36 +00:00
}
2014-06-28 21:22:05 +00:00
#endregion
2014-12-22 04:07:04 +00:00
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
{
2017-01-08 07:54:09 +00:00
if ( SAV . Edited ) { WinFormsUtil . Alert ( "Save has been edited. Cannot integrity check." ) ; return ; }
2014-06-28 21:22:05 +00:00
2017-01-08 07:54:09 +00:00
if ( SAV . ChecksumsValid ) { WinFormsUtil . Alert ( "Checksums are valid." ) ; return ; }
if ( DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Export Checksum Info to Clipboard?" ) )
2016-02-09 23:30:10 +00:00
Clipboard . SetText ( SAV . ChecksumInfo ) ;
2014-06-28 21:22:05 +00:00
}
2016-01-03 06:31:04 +00:00
private void clickExportSAVBAK ( object sender , EventArgs e )
2015-08-07 05:32:12 +00:00
{
2016-04-07 01:36:10 +00:00
if ( ! SAV . Exportable )
return ;
2016-01-03 06:31:04 +00:00
SaveFileDialog sfd = new SaveFileDialog
2016-02-12 05:41:31 +00:00
{ FileName = Util . CleanFileName ( SAV . BAKName ) } ;
2016-01-03 06:31:04 +00:00
if ( sfd . ShowDialog ( ) ! = DialogResult . OK )
return ;
2015-12-18 02:55:59 +00:00
2016-01-03 06:31:04 +00:00
string path = sfd . FileName ;
2016-01-28 04:24:32 +00:00
File . WriteAllBytes ( path , SAV . BAK ) ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Saved Backup of current SAV to:" , path ) ;
2016-02-12 05:41:31 +00:00
2016-12-04 19:23:10 +00:00
if ( ! Directory . Exists ( BackupPath ) )
promptBackup ( ) ;
}
private static void promptBackup ( )
{
2017-01-08 07:54:09 +00:00
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo ,
2017-01-08 23:27:00 +00:00
$"PKHeX can perform automatic backups if you create a folder with the name \" { BackupPath } \ " in the same folder as PKHeX's executable." ,
2016-12-04 19:23:10 +00:00
"Would you like to create the backup folder now?" ) ) return ;
2016-03-05 04:48:27 +00:00
2017-01-08 07:54:09 +00:00
try { Directory . CreateDirectory ( BackupPath ) ; WinFormsUtil . Alert ( "Backup folder created!" ,
2016-03-05 04:48:27 +00:00
$"If you wish to no longer automatically back up save files, delete the \" { BackupPath } \ " folder." ) ; }
2017-01-08 07:54:09 +00:00
catch ( Exception ex ) { WinFormsUtil . Error ( $"Unable to create backup folder @ {BackupPath}" , ex ) ; }
2016-01-03 06:31:04 +00:00
}
private void clickExportSAV ( object sender , EventArgs e )
{
if ( ! Menu_ExportSAV . Enabled )
return ;
2017-03-13 00:01:48 +00:00
ValidateChildren ( ) ;
2015-12-18 02:55:59 +00:00
2015-09-21 03:34:09 +00:00
// Chunk Error Checking
2016-06-20 04:22:43 +00:00
string err = SAV . MiscSaveChecks ( ) ;
2017-01-08 07:54:09 +00:00
if ( err . Length > 0 & & WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , err , "Continue saving?" ) ! = DialogResult . Yes )
2015-10-24 23:52:25 +00:00
return ;
2015-03-11 01:44:51 +00:00
2016-02-01 07:15:54 +00:00
SaveFileDialog main = new SaveFileDialog
{
2016-06-20 05:11:53 +00:00
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 ;
2015-03-11 01:44:51 +00:00
2015-09-21 03:34:09 +00:00
// Export
2016-02-01 07:15:54 +00:00
if ( main . ShowDialog ( ) ! = DialogResult . OK ) return ;
2016-02-11 08:56:10 +00:00
2016-06-20 04:22:43 +00:00
if ( SAV . HasBox )
2016-02-11 08:56:10 +00:00
SAV . CurrentBox = CB_BoxSelect . SelectedIndex ;
2016-06-20 05:11:53 +00:00
2016-07-18 18:51:26 +00:00
bool dsv = Path . GetExtension ( main . FileName ) ? . ToLower ( ) = = ".dsv" ;
2017-04-02 14:53:46 +00:00
bool gci = Path . GetExtension ( main . FileName ) ? . ToLower ( ) = = ".gci" ;
2017-01-07 04:40:22 +00:00
try
{
2017-04-02 14:53:46 +00:00
File . WriteAllBytes ( main . FileName , SAV . Write ( dsv , gci ) ) ;
2017-01-07 04:40:22 +00:00
SAV . Edited = false ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "SAV exported to:" , main . FileName ) ;
2017-01-07 04:40:22 +00:00
}
2017-01-28 21:07:44 +00:00
catch ( Exception x )
2017-01-07 04:40:22 +00:00
{
2017-05-11 01:52:49 +00:00
if ( x is UnauthorizedAccessException | | x is FileNotFoundException | | x is IOException )
2017-01-28 21:07:44 +00:00
WinFormsUtil . Error ( "Unable to save." + Environment . NewLine + x . Message ,
"If destination is a removable disk (SD card), please ensure the write protection switch is not set." ) ;
else throw ;
2017-01-07 04:40:22 +00:00
}
2014-06-28 21:22:05 +00:00
}
2016-01-28 04:24:32 +00:00
2014-12-28 21:56:59 +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
{
2016-06-20 04:22:43 +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
{
2016-06-20 04:22:43 +00:00
CB_BoxSelect . SelectedIndex = ( CB_BoxSelect . SelectedIndex + SAV . BoxCount - 1 ) % SAV . BoxCount ;
2014-06-28 21:22:05 +00:00
}
2016-02-09 07:57:25 +00:00
private void clickBoxSort ( object sender , EventArgs e )
{
2016-08-31 04:12:47 +00:00
if ( tabBoxMulti . SelectedTab ! = Tab_Box )
2016-02-09 07:57:25 +00:00
return ;
2016-07-15 03:37:18 +00:00
if ( ! SAV . HasBox )
return ;
2016-02-09 07:57:25 +00:00
2016-09-16 01:37:40 +00:00
string modified ;
2016-11-09 01:30:27 +00:00
bool all = false ;
2017-01-08 07:54:09 +00:00
if ( ModifierKeys = = ( Keys . Alt | Keys . Shift ) & & DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Clear ALL Boxes?!" ) )
2016-09-16 01:37:40 +00:00
{
2016-12-16 07:17:17 +00:00
if ( SAV . getBoxHasLockedSlot ( 0 , SAV . BoxCount - 1 ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Battle Box slots prevent the clearing of all boxes." ) ; return ; }
2016-06-20 04:22:43 +00:00
SAV . resetBoxes ( ) ;
2016-09-16 01:37:40 +00:00
modified = "Boxes cleared!" ;
2016-11-09 01:30:27 +00:00
all = true ;
2016-06-20 04:22:43 +00:00
}
2017-01-08 07:54:09 +00:00
else if ( ModifierKeys = = Keys . Alt & & DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Clear Current Box?" ) )
2016-06-20 04:22:43 +00:00
{
2016-12-16 07:17:17 +00:00
if ( SAV . getBoxHasLockedSlot ( CB_BoxSelect . SelectedIndex , CB_BoxSelect . SelectedIndex ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Battle Box slots prevent the clearing of box." ) ; return ; }
2016-06-20 04:22:43 +00:00
SAV . resetBoxes ( CB_BoxSelect . SelectedIndex , CB_BoxSelect . SelectedIndex + 1 ) ;
2016-09-16 01:37:40 +00:00
modified = "Current Box cleared!" ;
2016-06-20 04:22:43 +00:00
}
2017-01-08 07:54:09 +00:00
else if ( ModifierKeys = = ( Keys . Control | Keys . Shift ) & & DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Sort ALL Boxes?!" ) )
2016-06-20 04:22:43 +00:00
{
2016-12-16 07:17:17 +00:00
if ( SAV . getBoxHasLockedSlot ( 0 , SAV . BoxCount - 1 ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Battle Box slots prevent the sorting of all boxes." ) ; return ; }
2016-06-20 04:22:43 +00:00
SAV . sortBoxes ( ) ;
2016-09-16 01:37:40 +00:00
modified = "Boxes sorted!" ;
2016-11-09 01:30:27 +00:00
all = true ;
2016-06-20 04:22:43 +00:00
}
2017-01-08 07:54:09 +00:00
else if ( ModifierKeys = = Keys . Control & & DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Sort Current Box?" ) )
2016-06-20 04:22:43 +00:00
{
2016-12-16 07:17:17 +00:00
if ( SAV . getBoxHasLockedSlot ( CB_BoxSelect . SelectedIndex , CB_BoxSelect . SelectedIndex ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Battle Box slots prevent the sorting of box." ) ; return ; }
2016-06-20 04:22:43 +00:00
SAV . sortBoxes ( CB_BoxSelect . SelectedIndex , CB_BoxSelect . SelectedIndex + 1 ) ;
2016-09-16 01:37:40 +00:00
modified = "Current Box sorted!" ;
2016-06-20 04:22:43 +00:00
}
2016-09-16 01:37:40 +00:00
else
return ;
setPKXBoxes ( ) ;
2016-11-09 01:30:27 +00:00
updateBoxViewers ( all ) ;
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( modified ) ;
2016-08-29 03:13:52 +00:00
}
private void clickBoxDouble ( object sender , MouseEventArgs e )
{
2016-08-31 04:12:47 +00:00
if ( tabBoxMulti . SelectedTab = = Tab_SAV )
{
clickSaveFileName ( sender , e ) ;
return ;
}
if ( tabBoxMulti . SelectedTab ! = Tab_Box )
2016-08-29 03:13:52 +00:00
return ;
if ( ! SAV . HasBox )
return ;
if ( ModifierKeys ! = Keys . Shift )
2016-08-26 01:50:51 +00:00
{
var z = Application . OpenForms . Cast < Form > ( ) . FirstOrDefault ( form = > form . GetType ( ) = = typeof ( SAV_BoxViewer ) ) as SAV_BoxViewer ;
if ( z ! = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . CenterToForm ( z , this ) ; z . BringToFront ( ) ; return ; }
2016-08-26 01:50:51 +00:00
}
2016-08-29 03:13:52 +00:00
new SAV_BoxViewer ( this ) . Show ( ) ;
2016-08-26 01:50:51 +00:00
}
public int swapBoxesViewer ( int viewBox )
{
int mainBox = CB_BoxSelect . SelectedIndex ;
CB_BoxSelect . SelectedIndex = viewBox ;
return mainBox ;
2016-02-09 07:57:25 +00:00
}
2016-09-14 04:17:07 +00:00
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 ( ) ;
}
2016-11-09 01:30:27 +00:00
private void updateBoxViewers ( bool all = false )
2016-09-16 01:37:40 +00:00
{
var views = Application . OpenForms . OfType < SAV_BoxViewer > ( ) ;
2016-11-09 01:30:27 +00:00
foreach ( var v in views . Where ( v = > v . CurrentBox = = CB_BoxSelect . SelectedIndex | | all ) )
2016-09-16 01:37:40 +00:00
v . setPKXBoxes ( ) ;
}
2016-06-20 04:22:43 +00:00
2014-12-24 07:29:57 +00:00
private void clickSlot ( object sender , EventArgs e )
{
2015-03-11 01:44:51 +00:00
switch ( ModifierKeys )
{
2016-01-18 01:07:19 +00:00
case Keys . Control | Keys . Alt : clickClone ( sender , e ) ; break ;
2015-03-11 01:44:51 +00:00
case Keys . Control : clickView ( sender , e ) ; break ;
case Keys . Shift : clickSet ( sender , e ) ; break ;
case Keys . Alt : clickDelete ( sender , e ) ; break ;
}
2014-12-24 07:29:57 +00:00
}
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 ) ;
2015-10-15 03:10:09 +00:00
if ( SlotPictureBoxes [ slot ] . Image = = null )
2016-01-03 18:47:44 +00:00
{ SystemSounds . Exclamation . Play ( ) ; return ; }
2017-03-22 06:25:13 +00:00
if ( PKMIsUnsaved & & DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "PKM has been modified but has not been Set." , "Continue?" ) )
return ;
2016-06-20 04:22:43 +00:00
int offset = getPKXOffset ( slot ) ;
if ( offset < 0 )
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( $"Slot read error @ slot {slot}." ) ;
2016-06-20 04:22:43 +00:00
return ;
}
2014-06-28 21:22:05 +00:00
// Load the PKX file
2016-06-20 04:22:43 +00:00
PKM pk = 30 < = slot & & slot < 36 ? SAV . getPartySlot ( offset ) : SAV . getStoredSlot ( offset ) ;
2016-09-15 05:04:22 +00:00
if ( pk . Valid & & pk . Species ! = 0 )
2014-06-28 21:22:05 +00:00
{
2016-01-28 04:24:32 +00:00
try { populateFields ( pk ) ; }
2016-06-20 04:22:43 +00:00
catch { }
2014-06-28 21:22:05 +00:00
// Visual to display what slot is currently loaded.
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotView ) ;
2014-06-28 21:22:05 +00:00
}
2014-07-31 22:06:48 +00:00
else
2016-01-03 18:47:44 +00:00
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
{
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) ) return ;
2014-06-28 21:22:05 +00:00
int slot = getSlot ( sender ) ;
2016-01-28 04:24:32 +00:00
if ( slot = = 30 & & ( CB_Species . SelectedIndex = = 0 | | CHK_IsEgg . Checked ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Can't have empty/egg first slot." ) ; return ; }
2016-12-16 07:17:17 +00:00
if ( SAV . getIsSlotLocked ( CB_BoxSelect . SelectedIndex , slot ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Can't set to locked slot." ) ; return ; }
2014-10-11 07:22:22 +00:00
2016-01-28 04:24:32 +00:00
int offset = getPKXOffset ( slot ) ;
2016-06-20 04:22:43 +00:00
if ( offset < 0 )
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( $"Slot read error @ slot {slot}." ) ;
2016-04-24 19:40:46 +00:00
return ;
2016-06-20 04:22:43 +00:00
}
PKM pk = preparePKM ( ) ;
2016-06-21 06:02:26 +00:00
2017-02-04 22:58:30 +00:00
string [ ] errata = SAV . IsPKMCompatible ( pk ) ;
2017-01-08 07:54:09 +00:00
if ( errata . Length > 0 & & DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , string . Join ( Environment . NewLine , errata ) , "Continue?" ) )
2016-06-21 06:02:26 +00:00
return ;
2014-07-26 21:56:06 +00:00
if ( slot > = 30 & & slot < 36 ) // Party
2016-07-05 03:04:43 +00:00
{
2016-07-05 03:11:28 +00:00
// If slot isn't overwriting existing PKM, make it write to the lowest empty PKM slot
2016-07-05 03:04:43 +00:00
if ( SAV . PartyCount < slot + 1 - 30 )
{ slot = SAV . PartyCount + 30 ; offset = getPKXOffset ( slot ) ; }
2016-06-20 04:22:43 +00:00
SAV . setPartySlot ( pk , offset ) ;
2016-07-05 03:04:43 +00:00
setParty ( ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotSet ) ;
2016-07-05 03:04:43 +00:00
}
2017-03-20 07:03:31 +00:00
else if ( slot < 30 | | HaX )
2016-07-05 03:04:43 +00:00
{
2016-10-04 02:27:48 +00:00
if ( slot < 30 )
{
UndoStack . Push ( new SlotChange
{
Box = CB_BoxSelect . SelectedIndex ,
Slot = slot ,
Offset = offset ,
OriginalData = SAV . getStoredSlot ( offset )
} ) ;
Menu_Undo . Enabled = true ;
}
2016-06-20 04:22:43 +00:00
SAV . setStoredSlot ( pk , offset ) ;
2016-01-24 18:19:30 +00:00
getQuickFiller ( SlotPictureBoxes [ slot ] , pk ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotSet ) ;
2016-07-05 03:04:43 +00:00
}
2016-09-16 01:08:15 +00:00
2017-03-22 06:25:13 +00:00
lastData = pk . Data ;
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2016-10-04 04:41:59 +00:00
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 ) ;
2016-12-16 07:17:17 +00:00
if ( slot = = 30 & & SAV . PartyCount = = 1 & & ! HaX )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Can't delete first slot." ) ; return ; }
2016-12-16 07:17:17 +00:00
if ( SAV . getIsSlotLocked ( CB_BoxSelect . SelectedIndex , slot ) )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Can't delete locked slot." ) ; return ; }
2016-06-20 04:22:43 +00:00
int offset = getPKXOffset ( slot ) ;
if ( offset < 0 )
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Error ( $"Slot read error @ slot {slot}." ) ;
2016-06-20 04:22:43 +00:00
return ;
}
2014-10-11 07:22:22 +00:00
if ( slot > = 30 & & slot < 36 ) // Party
2016-07-05 03:04:43 +00:00
{
SAV . deletePartySlot ( slot - 30 ) ;
setParty ( ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotDel ) ;
2016-07-05 03:04:43 +00:00
return ;
}
2017-03-20 07:03:31 +00:00
if ( slot < 30 | | HaX )
2016-10-04 02:27:48 +00:00
{
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 ;
2016-09-04 06:19:11 +00:00
getQuickFiller ( SlotPictureBoxes [ slot ] , SAV . BlankPKM ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotDel ) ;
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2016-10-04 04:41:59 +00:00
RedoStack . Clear ( ) ; Menu_Redo . Enabled = false ;
2014-10-11 07:22:22 +00:00
}
2016-10-04 02:27:48 +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 ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( slot , Resources . slotSet ) ;
2016-10-04 02:27:48 +00:00
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 )
2014-11-29 19:07:01 +00:00
{
2014-12-06 02:14:04 +00:00
if ( getSlot ( sender ) > 30 ) return ; // only perform action if cloning to boxes
2016-06-21 06:02:26 +00:00
if ( ! verifiedPKM ( ) ) return ; // don't copy garbage to the box
2016-07-03 03:30:20 +00:00
2017-01-08 07:54:09 +00:00
if ( WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , $"Clone Pokemon from Editing Tabs to all slots in {CB_BoxSelect.Text}?" ) ! = DialogResult . Yes )
2016-06-20 04:22:43 +00:00
return ;
2014-11-29 19:07:01 +00:00
2016-10-16 04:28:14 +00:00
PKM pk = preparePKM ( ) ;
2016-12-16 07:17:17 +00:00
int slotSkipped = 0 ;
2017-01-30 01:50:06 +00:00
for ( int i = 0 ; i < SAV . BoxSlotCount ; i + + ) // set to every slot in box
2015-10-24 03:13:32 +00:00
{
2016-12-16 07:17:17 +00:00
if ( SAV . getIsSlotLocked ( CB_BoxSelect . SelectedIndex , i ) )
{ slotSkipped + + ; continue ; }
2016-06-20 04:22:43 +00:00
SAV . setStoredSlot ( pk , getPKXOffset ( i ) ) ;
2016-01-24 18:19:30 +00:00
getQuickFiller ( SlotPictureBoxes [ i ] , pk ) ;
2015-10-24 03:13:32 +00:00
}
2016-12-16 07:17:17 +00:00
if ( slotSkipped > 0 )
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( $"Skipped {slotSkipped} locked slot{(slotSkipped > 1 ? " s " : " ")}." ) ;
2016-12-16 07:17:17 +00:00
2016-09-16 01:37:40 +00:00
updateBoxViewers ( ) ;
2014-11-29 19:07:01 +00:00
}
2016-03-09 03:20:26 +00:00
private void clickLegality ( object sender , EventArgs e )
{
int slot = getSlot ( sender ) ;
2016-06-20 04:22:43 +00:00
PKM pk ;
2016-03-09 03:20:26 +00:00
if ( slot > = 0 )
2017-02-03 03:27:48 +00:00
{
2016-06-20 04:22:43 +00:00
pk = SAV . getStoredSlot ( getPKXOffset ( slot ) ) ;
2017-02-03 03:27:48 +00:00
if ( slot < 30 | | slot > = 36 ) // not party
pk . Box = CB_BoxSelect . SelectedIndex ; // mark as in a box
}
2016-06-21 06:02:26 +00:00
else if ( verifiedPKM ( ) )
2016-06-20 04:22:43 +00:00
pk = preparePKM ( ) ;
2016-03-09 03:20:26 +00:00
else
return ;
if ( pk . Species = = 0 | | ! pk . ChecksumValid )
{ SystemSounds . Asterisk . Play ( ) ; return ; }
2016-10-23 19:48:49 +00:00
showLegality ( pk , slot < 0 , ModifierKeys = = Keys . Control ) ;
2016-03-09 03:20:26 +00:00
}
2016-10-04 02:27:48 +00:00
private void updateSaveSlot ( object sender , EventArgs e )
{
if ( SAV . Version ! = GameVersion . BATREV )
return ;
2017-01-08 07:54:09 +00:00
( ( SAV4BR ) SAV ) . CurrentSlot = WinFormsUtil . getIndex ( CB_SaveSlot ) ;
2016-10-04 02:27:48 +00:00
setPKXBoxes ( ) ;
}
2016-12-28 22:35:14 +00:00
private void updateStringSeed ( object sender , EventArgs e )
2015-09-16 06:33:02 +00:00
{
2016-12-28 22:35:14 +00:00
if ( ! fieldsLoaded )
return ;
2015-09-16 06:33:02 +00:00
2016-12-28 22:35:14 +00:00
TextBox tb = sender as TextBox ;
if ( tb = = null )
return ;
2015-09-16 06:33:02 +00:00
2016-12-10 20:27:37 +00:00
if ( tb . Text . Length = = 0 )
{
2016-12-28 22:35:14 +00:00
tb . Undo ( ) ;
return ;
2016-12-10 20:27:37 +00:00
}
string filterText = Util . getOnlyHex ( tb . Text ) ;
if ( filterText . Length ! = tb . Text . Length )
{
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Expected HEX (0-9, A-F)." , "Received: " + Environment . NewLine + tb . Text ) ;
2016-12-28 22:35:14 +00:00
tb . Undo ( ) ;
return ;
2016-12-10 20:27:37 +00:00
}
// Write final value back to the save
2016-12-28 22:35:14 +00:00
if ( tb = = TB_RNGSeed )
2016-12-10 20:27:37 +00:00
{
2016-12-28 22:35:14 +00:00
var value = filterText . PadLeft ( SAV . DaycareSeedSize , '0' ) ;
SAV . setDaycareRNGSeed ( SAV . DaycareIndex , value ) ;
2016-12-10 20:27:37 +00:00
SAV . Edited = true ;
}
2016-12-28 22:35:14 +00:00
else if ( tb = = TB_GameSync )
2016-07-19 03:36:52 +00:00
{
2016-12-28 22:35:14 +00:00
var value = filterText . PadLeft ( SAV . GameSyncIDSize , '0' ) ;
SAV . GameSyncID = value ;
SAV . Edited = true ;
2015-12-28 21:52:08 +00:00
}
2016-12-28 22:35:14 +00:00
else if ( SAV . Generation > = 6 )
2016-06-20 04:22:43 +00:00
{
2016-12-28 22:35:14 +00:00
var value = Convert . ToUInt64 ( filterText , 16 ) ;
2016-12-10 20:27:37 +00:00
if ( tb = = TB_Secure1 )
2016-12-28 22:35:14 +00:00
SAV . Secure1 = value ;
2016-06-20 04:22:43 +00:00
else if ( tb = = TB_Secure2 )
2016-12-28 22:35:14 +00:00
SAV . Secure2 = value ;
2015-12-28 21:52:08 +00:00
SAV . Edited = true ;
}
}
2016-08-29 20:27:17 +00:00
private void updateIsNicknamed ( object sender , EventArgs e )
{
2016-09-28 05:43:03 +00:00
if ( ! fieldsLoaded )
return ;
2016-10-12 05:59:19 +00:00
2017-02-04 05:48:43 +00:00
pkm . Nickname = TB_Nickname . Text ;
if ( CHK_Nicknamed . Checked )
return ;
int species = WinFormsUtil . getIndex ( CB_Species ) ;
if ( species < 1 | | species > SAV . MaxSpeciesID )
return ;
if ( CHK_IsEgg . Checked )
species = 0 ; // get the egg name.
2017-02-05 02:27:28 +00:00
if ( PKX . getIsNicknamedAnyLanguage ( species , TB_Nickname . Text , SAV . Generation ) )
2017-02-04 05:48:43 +00:00
CHK_Nicknamed . Checked = true ;
2016-08-29 20:27:17 +00:00
}
2015-10-24 03:13:32 +00:00
// Generic Subfunctions //
2016-12-18 03:05:22 +00:00
public void setParty ( )
2014-07-26 21:56:06 +00:00
{
2016-06-20 04:22:43 +00:00
PKM [ ] party = SAV . PartyData ;
PKM [ ] battle = SAV . BattleBoxData ;
2015-02-27 16:18:32 +00:00
// Refresh slots
2016-06-20 04:22:43 +00:00
if ( SAV . HasParty )
2016-07-05 03:04:43 +00:00
{
for ( int i = 0 ; i < party . Length ; i + + )
2016-06-20 04:22:43 +00:00
getQuickFiller ( SlotPictureBoxes [ i + 30 ] , party [ i ] ) ;
2016-07-05 03:04:43 +00:00
for ( int i = party . Length ; i < 6 ; i + + )
SlotPictureBoxes [ i + 30 ] . Image = null ;
}
2016-06-20 04:22:43 +00:00
if ( SAV . HasBattleBox )
2016-07-05 03:04:43 +00:00
{
for ( int i = 0 ; i < battle . Length ; i + + )
2016-06-20 04:22:43 +00:00
getQuickFiller ( SlotPictureBoxes [ i + 36 ] , battle [ i ] ) ;
2016-07-05 03:04:43 +00:00
for ( int i = battle . Length ; i < 6 ; i + + )
2016-08-03 06:51:58 +00:00
SlotPictureBoxes [ i + 36 ] . Image = null ;
2016-07-05 03:04:43 +00:00
}
2014-06-28 21:22:05 +00:00
}
private int getPKXOffset ( int slot )
{
2016-04-26 05:03:16 +00:00
if ( slot < 30 ) // Box Slot
2016-06-20 04:22:43 +00:00
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
2016-01-31 07:03:43 +00:00
return SAV . GTS ;
2016-06-20 04:22:43 +00:00
slot - = 1 ;
if ( slot = = 0 ) // Fused
2016-01-31 07:03:43 +00:00
return SAV . Fused ;
2016-06-20 04:22:43 +00:00
slot - = 1 ;
if ( slot < 3 ) // SUBE
return SAV . SUBE + slot * ( SAV . SIZE_STORED + 4 ) ;
2016-01-31 07:03:43 +00:00
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 ;
2016-01-31 07:03:43 +00:00
return Array . IndexOf ( SlotPictureBoxes , sender ) ;
2014-06-28 21:22:05 +00:00
}
2015-11-15 02:17:54 +00:00
public void setPKXBoxes ( )
2014-06-28 21:22:05 +00:00
{
2016-06-20 04:22:43 +00:00
if ( SAV . HasBox )
2015-12-30 06:03:27 +00:00
{
2016-06-20 04:22:43 +00:00
int boxoffset = SAV . getBoxOffset ( CB_BoxSelect . SelectedIndex ) ;
2016-07-25 04:11:11 +00:00
int boxbgval = SAV . getBoxWallpaper ( CB_BoxSelect . SelectedIndex ) ;
2017-01-12 06:28:35 +00:00
PAN_Box . BackgroundImage = SAV . WallpaperImage ( boxbgval ) ;
2015-12-30 06:03:27 +00:00
for ( int i = 0 ; i < 30 ; i + + )
2016-08-28 10:18:22 +00:00
{
if ( i < SAV . BoxSlotCount )
2016-08-29 05:21:55 +00:00
{
getSlotFiller ( boxoffset + SAV . SIZE_STORED * i , SlotPictureBoxes [ i ] ) ;
}
2016-08-28 10:18:22 +00:00
else
{
SlotPictureBoxes [ i ] . Image = null ;
2016-08-29 05:21:55 +00:00
SlotPictureBoxes [ i ] . Visible = false ;
2016-08-28 10:18:22 +00:00
}
}
2015-12-30 06:03:27 +00:00
}
2014-06-28 21:22:05 +00:00
// Reload Party
2016-06-20 04:22:43 +00:00
if ( SAV . HasParty )
{
for ( int i = 0 ; i < 6 ; i + + )
getSlotFiller ( SAV . getPartyOffset ( i ) , SlotPictureBoxes [ i + 30 ] ) ;
}
2014-12-06 02:14:04 +00:00
2014-06-28 21:22:05 +00:00
// Reload Battle Box
2016-06-20 04:22:43 +00:00
if ( SAV . HasBattleBox )
{
for ( int i = 0 ; i < 6 ; i + + )
getSlotFiller ( SAV . BattleBox + SAV . SIZE_STORED * i , SlotPictureBoxes [ i + 36 ] ) ;
}
2014-12-06 02:14:04 +00:00
2014-06-28 21:22:05 +00:00
// Reload Daycare
2016-06-20 04:22:43 +00:00
if ( SAV . HasDaycare )
2014-06-28 21:22:05 +00:00
{
2016-06-20 04:22:43 +00:00
Label [ ] L_SlotOccupied = { L_DC1 , L_DC2 } ;
TextBox [ ] TB_SlotEXP = { TB_Daycare1XP , TB_Daycare2XP } ;
Label [ ] L_SlotEXP = { L_XP1 , L_XP2 } ;
2015-12-30 06:03:27 +00:00
for ( int i = 0 ; i < 2 ; i + + )
2014-06-28 21:22:05 +00:00
{
2016-06-20 04:22:43 +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}: ✓" ;
2015-12-30 06:03:27 +00:00
else
{
2016-06-20 04:22:43 +00:00
L_SlotOccupied [ i ] . Text = $"{i + 1}: ✘" ;
2017-01-12 01:55:42 +00:00
SlotPictureBoxes [ i + 42 ] . Image = ImageUtil . ChangeOpacity ( SlotPictureBoxes [ i + 42 ] . Image , 0.6 ) ;
2015-12-30 06:03:27 +00:00
}
2014-06-28 21:22:05 +00:00
}
2016-06-20 04:22:43 +00:00
bool? egg = SAV . getDaycareHasEgg ( SAV . DaycareIndex ) ;
DayCare_HasEgg . Visible = egg ! = null ;
DayCare_HasEgg . Checked = egg = = true ;
2016-10-30 02:11:47 +00:00
var seed = SAV . getDaycareRNGSeed ( SAV . DaycareIndex ) ;
2016-06-20 04:22:43 +00:00
L_DaycareSeed . Visible = TB_RNGSeed . Visible = seed ! = null ;
if ( seed ! = null )
{
TB_RNGSeed . MaxLength = SAV . DaycareSeedSize ;
2016-10-30 02:11:47 +00:00
TB_RNGSeed . Text = seed ;
2016-06-20 04:22:43 +00:00
}
2014-06-28 21:22:05 +00:00
}
// GTS
2016-06-20 04:22:43 +00:00
if ( SAV . HasGTS )
2015-10-24 03:13:32 +00:00
getSlotFiller ( SAV . GTS , SlotPictureBoxes [ 44 ] ) ;
2014-06-28 21:22:05 +00:00
// Fused
2016-06-20 04:22:43 +00:00
if ( SAV . HasFused )
2015-10-24 03:13:32 +00:00
getSlotFiller ( SAV . Fused , SlotPictureBoxes [ 45 ] ) ;
2014-06-28 21:22:05 +00:00
// SUBE
2016-06-20 04:22:43 +00:00
if ( SAV . HasSUBE )
2014-06-28 21:22:05 +00:00
for ( int i = 0 ; i < 3 ; i + + )
{
2016-06-20 04:22:43 +00:00
int offset = SAV . SUBE + i * ( SAV . SIZE_STORED + 4 ) ;
2015-10-24 03:13:32 +00:00
if ( BitConverter . ToUInt64 ( SAV . Data , offset ) ! = 0 )
2015-09-21 03:34:09 +00:00
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)
2016-06-20 04:22:43 +00:00
if ( colorizedslot < = SAV . BoxCount )
2016-01-05 06:42:38 +00:00
SlotPictureBoxes [ colorizedslot ] . BackgroundImage = colorizedbox = = CB_BoxSelect . SelectedIndex ? colorizedcolor : null ;
2014-06-28 21:22:05 +00:00
}
2014-12-24 07:29:57 +00:00
private void setBoxNames ( )
2014-06-28 21:22:05 +00:00
{
2016-06-20 04:22:43 +00:00
if ( ! SAV . HasBox )
2015-12-30 06:03:27 +00:00
return ;
2014-06-28 21:22:05 +00:00
// Build ComboBox Dropdown Items
try
{
2015-05-07 02:30:31 +00:00
CB_BoxSelect . Items . Clear ( ) ;
2016-06-20 04:22:43 +00:00
for ( int i = 0 ; i < SAV . BoxCount ; i + + )
2015-10-24 23:33:44 +00:00
CB_BoxSelect . Items . Add ( SAV . getBoxName ( i ) ) ;
2014-06-28 21:22:05 +00:00
}
catch
{
2015-05-07 02:30:31 +00:00
CB_BoxSelect . Items . Clear ( ) ;
2016-08-26 01:50:51 +00:00
for ( int i = 1 ; i < = SAV . BoxCount ; i + + )
CB_BoxSelect . Items . Add ( $"BOX {i}" ) ;
2014-06-28 21:22:05 +00:00
}
2016-10-02 23:48:12 +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
}
2016-06-20 04:22:43 +00:00
private void getQuickFiller ( PictureBox pb , PKM pk = null )
2014-12-14 20:15:53 +00:00
{
2015-11-06 06:59:55 +00:00
if ( ! fieldsInitialized ) return ;
2016-06-20 04:22:43 +00:00
pk = pk ? ? preparePKM ( false ) ; // don't perform control loss click
2014-12-14 20:15:53 +00:00
2016-03-12 02:40:08 +00:00
if ( pb = = dragout ) mnuLQR . Enabled = pk . Species ! = 0 ; // Species
2016-12-16 07:17:17 +00:00
int slot = getSlot ( pb ) ;
2017-02-05 04:39:42 +00:00
pb . Image = pk . Sprite ( SAV , CB_BoxSelect . SelectedIndex , slot , Menu_FlagIllegal . Checked ) ;
2016-03-24 04:35:36 +00:00
if ( pb . BackColor = = Color . Red )
pb . BackColor = Color . Transparent ;
2014-12-14 20:15:53 +00:00
}
2014-06-28 21:22:05 +00:00
private void getSlotFiller ( int offset , PictureBox pb )
{
2016-06-20 04:22:43 +00:00
if ( SAV . getData ( offset , SAV . SIZE_STORED ) . SequenceEqual ( new byte [ SAV . SIZE_STORED ] ) )
2015-10-15 01:33:51 +00:00
{
2015-12-02 07:08:16 +00:00
// 00s present in slot.
2015-10-15 01:33:51 +00:00
pb . Image = null ;
pb . BackColor = Color . Transparent ;
2016-08-29 05:21:55 +00:00
pb . Visible = true ;
2015-10-15 01:33:51 +00:00
return ;
}
2016-06-20 04:22:43 +00:00
PKM p = SAV . getStoredSlot ( offset ) ;
2016-09-15 05:04:22 +00:00
if ( ! p . Valid ) // Invalid
2014-08-07 00:10:29 +00:00
{
2015-04-28 14:39:50 +00:00
// Bad Egg present in slot.
2014-08-07 00:10:29 +00:00
pb . Image = null ;
pb . BackColor = Color . Red ;
2016-08-29 05:21:55 +00:00
pb . Visible = true ;
2014-08-07 00:10:29 +00:00
return ;
}
2016-12-16 07:17:17 +00:00
int slot = getSlot ( pb ) ;
2017-02-05 04:39:42 +00:00
pb . Image = p . Sprite ( SAV , CB_BoxSelect . SelectedIndex , slot , Menu_FlagIllegal . Checked ) ;
2015-12-02 07:08:16 +00:00
pb . BackColor = Color . Transparent ;
2016-08-29 05:21:55 +00:00
pb . Visible = true ;
2014-06-28 21:22:05 +00:00
}
2014-08-01 23:53:09 +00:00
private void getSlotColor ( int slot , Image color )
2014-06-28 21:22:05 +00:00
{
2015-10-25 01:16:22 +00:00
foreach ( PictureBox t in SlotPictureBoxes )
2015-03-11 01:44:51 +00:00
t . BackgroundImage = null ;
2014-08-17 01:42:51 +00:00
2016-01-31 07:03:43 +00:00
if ( slot < 30 )
2015-05-07 02:30:31 +00:00
colorizedbox = CB_BoxSelect . SelectedIndex ;
2014-08-17 01:42:51 +00:00
2015-10-25 01:16:22 +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 )
{
2016-10-02 23:48:12 +00:00
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
}
2014-12-28 21:56:59 +00:00
private void switchDaycare ( object sender , EventArgs e )
{
2016-10-23 19:48:49 +00:00
if ( ! SAV . HasTwoDaycares ) return ;
2017-01-08 07:54:09 +00:00
if ( DialogResult . Yes = = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Would you like to switch the view to the other Daycare?" ,
2016-03-29 09:58:14 +00:00
$"Currently viewing daycare {SAV.DaycareIndex + 1}." ) )
2015-01-01 19:38:37 +00:00
// If ORAS, alter the daycare offset via toggle.
2016-03-29 09:58:14 +00:00
SAV . DaycareIndex ^ = 1 ;
2014-12-28 21:56:59 +00:00
// Refresh Boxes
setPKXBoxes ( ) ;
}
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 ;
2016-06-20 04:22:43 +00:00
if ( ! SAV . HasBox ) return ;
2017-01-08 07:54:09 +00:00
DialogResult dr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel , "Clear subsequent boxes when importing data?" , "If you only want to overwrite for new data, press no." ) ;
2016-06-20 04:22:43 +00:00
if ( dr = = DialogResult . Cancel )
return ;
2016-05-06 01:52:43 +00:00
2017-02-04 22:58:30 +00:00
string result ;
bool clearAll = dr = = DialogResult . Yes ;
2016-06-20 04:22:43 +00:00
bool? noSetb = getPKMSetOverride ( ) ;
2017-02-04 22:58:30 +00:00
SAV . loadBoxes ( path , out result , CB_BoxSelect . SelectedIndex , clearAll , noSetb ) ;
2017-02-15 02:54:46 +00:00
setPKXBoxes ( ) ;
2017-02-04 22:58:30 +00:00
WinFormsUtil . 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
{
2016-06-20 04:22:43 +00:00
if ( ! SAV . HasBox )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "Save file does not have boxes to dump!" ) ; return ; }
2016-06-20 04:22:43 +00:00
2017-01-08 07:54:09 +00:00
DialogResult dr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel ,
2016-06-20 04:22:43 +00:00
"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 )
{
2015-03-11 01:44:51 +00:00
SaveFileDialog sfd = new SaveFileDialog { Filter = "Box Data|*.bin" , FileName = "pcdata.bin" } ;
2016-06-20 04:22:43 +00:00
if ( sfd . ShowDialog ( ) ! = DialogResult . OK )
return ;
File . WriteAllBytes ( sfd . FileName , SAV . getPCBin ( ) ) ;
2015-01-25 19:24:00 +00:00
}
2015-02-01 04:40:35 +00:00
else if ( dr = = DialogResult . No )
2015-01-24 19:16:20 +00:00
{
2016-06-20 04:22:43 +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
}
}
2016-06-20 04:22:43 +00:00
private bool? getPKMSetOverride ( )
2016-05-06 01:52:43 +00:00
{
2016-07-10 17:32:51 +00:00
var yn = Menu_ModifyPKM . Checked ? "Yes" : "No" ;
2017-01-08 07:54:09 +00:00
DialogResult noSet = WinFormsUtil . Prompt ( MessageBoxButtons . YesNoCancel ,
2016-06-20 04:22:43 +00:00
"Loading overrides:" ,
"Yes - Modify .pk* when set to SAV" + Environment . NewLine +
"No - Don't modify .pk*" + Environment . NewLine +
$"Cancel - Use current settings ({yn})" ) ;
2016-05-06 01:52:43 +00:00
return noSet = = DialogResult . Yes ? true : ( noSet = = DialogResult . No ? ( bool? ) false : null ) ;
}
2015-10-24 03:13:32 +00:00
2014-12-14 19:06:17 +00:00
// Subfunction Save Buttons //
2017-01-26 06:51:52 +00:00
private void B_OpenWondercards_Click ( object sender , EventArgs e ) = > new SAV_Wondercard ( sender as MysteryGift ) . ShowDialog ( ) ;
private void B_OpenPokepuffs_Click ( object sender , EventArgs e ) = > new SAV_Pokepuff ( ) . ShowDialog ( ) ;
private void B_OpenPokeBeans_Click ( object sender , EventArgs e ) = > new SAV_Pokebean ( ) . ShowDialog ( ) ;
private void B_OpenItemPouch_Click ( object sender , EventArgs e ) = > new SAV_Inventory ( ) . ShowDialog ( ) ;
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 ( ) ;
private void B_OpenEventFlags_Click ( object sender , EventArgs e ) = > new SAV_EventFlags ( ) . ShowDialog ( ) ;
private void B_OpenSuperTraining_Click ( object sender , EventArgs e ) = > new SAV_SuperTrain ( ) . ShowDialog ( ) ;
private void B_OpenSecretBase_Click ( object sender , EventArgs e ) = > new SAV_SecretBase ( ) . ShowDialog ( ) ;
private void B_OpenZygardeCells_Click ( object sender , EventArgs e ) = > new SAV_ZygardeCell ( ) . ShowDialog ( ) ;
private void B_LinkInfo_Click ( object sender , EventArgs e ) = > new SAV_Link6 ( ) . ShowDialog ( ) ;
2014-06-28 21:22:05 +00:00
private void B_OpenBoxLayout_Click ( object sender , EventArgs e )
{
2015-09-21 03:34:09 +00:00
new SAV_BoxLayout ( CB_BoxSelect . SelectedIndex ) . ShowDialog ( ) ;
2014-12-06 02:14:04 +00:00
setBoxNames ( ) ; // fix box names
setPKXBoxes ( ) ; // refresh box background
2016-11-09 01:30:27 +00:00
updateBoxViewers ( all : true ) ; // update subviewers
2014-06-28 21:22:05 +00:00
}
private void B_OpenTrainerInfo_Click ( object sender , EventArgs e )
{
2016-06-22 00:35:12 +00:00
if ( SAV . Generation < 6 )
new SAV_SimpleTrainer ( ) . ShowDialog ( ) ;
else if ( SAV . Generation = = 6 )
new SAV_Trainer ( ) . ShowDialog ( ) ;
2016-10-28 04:30:21 +00:00
else if ( SAV . Generation = = 7 )
new SAV_Trainer7 ( ) . ShowDialog ( ) ;
2016-06-20 04:22:43 +00:00
// Refresh conversion info
2017-01-26 06:51:52 +00:00
PKMConverter . updateConfig ( SAV . SubRegion , SAV . Country , SAV . ConsoleRegion , SAV . OT , SAV . Gender , SAV . Language ) ;
2014-07-31 22:06:48 +00:00
}
2014-07-27 01:00:17 +00:00
private void B_OpenOPowers_Click ( object sender , EventArgs e )
{
2016-06-20 04:22:43 +00:00
if ( SAV . Generation ! = 6 )
return ;
2015-10-24 03:13:32 +00:00
if ( SAV . ORAS )
2014-11-25 03:53:10 +00:00
{
2017-01-08 07:54:09 +00:00
DialogResult dr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "No editing support for ORAS :(" , "Max O-Powers with a working code?" ) ;
2015-03-11 01:44:51 +00:00
if ( dr ! = DialogResult . Yes ) return ;
2016-02-03 04:05:46 +00:00
new byte [ ]
2015-03-11 01:44:51 +00:00
{
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 ,
2016-06-20 04:22:43 +00:00
0x01 , 0x00 , 0x00 , 0x00 ,
2016-07-18 18:51:26 +00:00
} . CopyTo ( SAV . Data , ( ( SAV6 ) SAV ) . OPower ) ;
2014-11-25 03:53:10 +00:00
}
2016-04-26 05:03:16 +00:00
else if ( SAV . XY )
2015-09-21 03:34:09 +00:00
new SAV_OPower ( ) . ShowDialog ( ) ;
2014-07-27 01:00:17 +00:00
}
2017-04-05 01:58:32 +00:00
private void B_OpenFriendSafari_Click ( object sender , EventArgs e )
{
if ( ! SAV . XY )
return ;
DialogResult dr = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "No editing support for Friend Safari :(" , "Unlock all 3 slots for each friend?" ) ;
if ( dr ! = DialogResult . Yes ) return ;
// Unlock + reveal all safari slots if friend data is present
for ( int i = 1 ; i < 101 ; i + + )
if ( SAV . Data [ 0x1E7FF + 0x15 * i ] ! = 0x00 ) // no friend data == 0x00
SAV . Data [ 0x1E7FF + 0x15 * i ] = 0x3D ;
}
2014-07-28 01:30:54 +00:00
private void B_OpenPokedex_Click ( object sender , EventArgs e )
{
2017-03-06 01:34:30 +00:00
switch ( SAV . Generation )
{
case 1 :
case 2 :
new SAV_SimplePokedex ( ) . ShowDialog ( ) ; break ;
case 3 :
if ( SAV . GameCube )
return ;
new SAV_SimplePokedex ( ) . ShowDialog ( ) ; break ;
2017-03-07 06:43:46 +00:00
case 4 :
if ( SAV is SAV4BR )
return ;
new SAV_Pokedex4 ( ) . ShowDialog ( ) ; break ;
2017-03-06 01:34:30 +00:00
case 5 :
2017-03-07 06:43:46 +00:00
new SAV_Pokedex5 ( ) . ShowDialog ( ) ; break ;
2017-03-06 01:34:30 +00:00
case 6 :
if ( SAV . ORAS )
new SAV_PokedexORAS ( ) . ShowDialog ( ) ;
else if ( SAV . XY )
new SAV_PokedexXY ( ) . ShowDialog ( ) ;
break ;
case 7 :
if ( SAV . SM )
new SAV_PokedexSM ( ) . ShowDialog ( ) ;
break ;
}
2014-07-28 01:30:54 +00:00
}
2017-03-10 03:38:57 +00:00
private void B_OpenMiscEditor_Click ( object sender , EventArgs e )
{
switch ( SAV . Generation )
{
case 3 :
new SAV_Misc3 ( ) . ShowDialog ( ) ; break ;
2017-04-08 09:00:22 +00:00
case 4 :
new SAV_Misc4 ( ) . ShowDialog ( ) ; break ;
2017-03-10 03:38:57 +00:00
}
}
2017-04-14 02:11:01 +00:00
private void B_OpenRTCEditor_Click ( object sender , EventArgs e )
{
switch ( SAV . Generation )
{
case 3 :
new SAV_RTC3 ( ) . ShowDialog ( ) ; break ;
}
}
2017-04-07 00:39:37 +00:00
private void B_OpenHoneyTreeEditor_Click ( object sender , EventArgs e )
{
switch ( SAV . Version )
{
case GameVersion . DP :
case GameVersion . Pt :
new SAV_HoneyTree ( ) . ShowDialog ( ) ; break ;
}
}
2014-06-28 21:22:05 +00:00
private void B_OUTPasserby_Click ( object sender , EventArgs e )
{
2016-06-20 04:22:43 +00:00
if ( SAV . Generation ! = 6 )
return ;
2017-01-08 07:54:09 +00:00
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Export Passerby Info to Clipboard?" ) )
2015-12-18 02:55:59 +00:00
return ;
string result = "PSS List" + Environment . NewLine ;
string [ ] headers = { "PSS Data - Friends" , "PSS Data - Acquaintances" , "PSS Data - Passerby" , } ;
2016-07-18 18:51:26 +00:00
int offset = ( ( SAV6 ) SAV ) . PSS ;
2014-06-28 21:22:05 +00:00
for ( int g = 0 ; g < 3 ; g + + )
{
2015-01-03 01:07:29 +00:00
result + = Environment . NewLine
+ "----" + Environment . NewLine
+ headers [ g ] + Environment . NewLine
+ "----" + Environment . NewLine ;
2015-03-11 01:44:51 +00:00
// 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 + + )
{
2015-10-24 03:13:32 +00:00
ulong unkn = BitConverter . ToUInt64 ( SAV . Data , r_offset ) ;
2015-01-03 01:07:29 +00:00
if ( unkn = = 0 ) break ; // No data present here
if ( i > 0 ) result + = Environment . NewLine + Environment . NewLine ;
2014-06-28 21:22:05 +00:00
2015-10-24 03:13:32 +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
2015-03-11 01:44:51 +00:00
// 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);
2015-10-24 03:13:32 +00:00
byte region = SAV . Data [ r_offset + 0x56 ] ;
byte country = SAV . Data [ r_offset + 0x57 ] ;
byte game = SAV . Data [ r_offset + 0x5A ] ;
2015-03-11 01:44:51 +00:00
// ulong outfit = BitConverter.ToUInt64(savefile, r_offset + 0x5C);
2015-10-24 03:13:32 +00:00
int favpkm = BitConverter . ToUInt16 ( SAV . Data , r_offset + 0x9C ) & 0x7FF ;
2015-03-11 01:44:51 +00:00
string gamename ;
2017-01-08 07:54:09 +00:00
try { gamename = GameInfo . Strings . gamelist [ game ] ; }
2015-03-11 01:44:51 +00:00
catch { gamename = "UNKNOWN GAME" ; }
2014-12-17 03:12:16 +00:00
2017-02-05 02:27:28 +00:00
var cr = GameInfo . getCountryRegionText ( country , region , curlanguage ) ;
2015-01-01 19:38:37 +00:00
result + =
2014-12-11 07:00:25 +00:00
"OT: " + otname + Environment . NewLine +
"Message: " + message + Environment . NewLine +
"Game: " + gamename + Environment . NewLine +
2017-02-05 02:27:28 +00:00
"Country: " + cr . Item1 + Environment . NewLine +
"Region: " + cr . Item2 + Environment . NewLine +
2017-01-08 07:54:09 +00:00
"Favorite: " + GameInfo . Strings . specieslist [ favpkm ] ;
2014-12-11 07:00:25 +00:00
2015-01-03 01:07:29 +00:00
r_offset + = 0xC8 ; // Advance to next entry
2014-06-28 21:22:05 +00:00
}
2015-01-03 01:07:29 +00:00
offset + = 0x5000 ; // Advance to next block
2014-06-28 21:22:05 +00:00
}
2015-12-18 02:55:59 +00:00
Clipboard . SetText ( result ) ;
2014-06-28 21:22:05 +00:00
}
private void B_OUTHallofFame_Click ( object sender , EventArgs e )
{
2017-01-17 06:40:28 +00:00
if ( SAV . Generation = = 6 )
new SAV_HallOfFame ( ) . ShowDialog ( ) ;
else if ( SAV . SM )
new SAV_HallOfFame7 ( ) . ShowDialog ( ) ;
2014-06-28 21:22:05 +00:00
}
2016-08-08 05:46:07 +00:00
private void B_CGearSkin_Click ( object sender , EventArgs e )
{
2016-11-23 02:40:41 +00:00
if ( SAV . Generation ! = 5 )
return ; // can never be too safe
2016-08-08 05:46:07 +00:00
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 )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Alert ( "No PGL picture data found in the save file!" ) ; return ; }
2016-03-05 06:09:54 +00:00
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
}
2014-12-24 07:29:57 +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
{
2017-01-08 07:54:09 +00:00
string path ;
string cgse = "" ;
string pathCache = CyberGadgetUtil . GetCacheFolder ( ) ;
if ( Directory . Exists ( pathCache ) )
cgse = Path . Combine ( pathCache ) ;
if ( ! SaveUtil . detectSaveFile ( out path , cgse ) )
WinFormsUtil . Error ( path ) ;
2016-06-20 04:22:43 +00:00
if ( path = = null | | ! File . Exists ( path ) ) return ;
2017-01-08 07:54:09 +00:00
if ( WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , "Open save file from the following location?" , path ) = = DialogResult . Yes )
2016-06-20 04:22:43 +00:00
openQuick ( path ) ; // load save
}
2014-11-26 04:43:02 +00:00
2016-08-05 11:04:56 +00:00
// Drag and drop related functions
2017-04-14 06:05:19 +00:00
private static Image OriginalBackground ;
private static Image CurrentBackground ;
private void pbBoxSlot_MouseEnter ( object sender , EventArgs e )
{
var pb = ( PictureBox ) sender ;
if ( pb . Image = = null )
return ;
OriginalBackground = pb . BackgroundImage ;
pb . BackgroundImage = CurrentBackground = Resources . slotHover ;
Cursor = Cursors . Hand ;
}
private void pbBoxSlot_MouseLeave ( object sender , EventArgs e )
{
var pb = ( PictureBox ) sender ;
if ( pb . BackgroundImage ! = CurrentBackground )
return ;
pb . BackgroundImage = OriginalBackground ;
Cursor = Cursors . Default ;
}
2016-08-05 11:04:56 +00:00
private void pbBoxSlot_MouseClick ( object sender , MouseEventArgs e )
{
2017-01-26 06:51:52 +00:00
if ( ! DragInfo . slotDragDropInProgress )
clickSlot ( sender , e ) ;
2016-08-05 11:04:56 +00:00
}
private void pbBoxSlot_MouseUp ( object sender , MouseEventArgs e )
{
if ( e . Button = = MouseButtons . Left )
2016-08-26 01:50:51 +00:00
DragInfo . slotLeftMouseIsDown = false ;
2016-08-05 11:04:56 +00:00
if ( e . Button = = MouseButtons . Right )
2016-08-26 01:50:51 +00:00
DragInfo . slotRightMouseIsDown = false ;
2016-08-05 11:04:56 +00:00
}
2014-11-26 04:43:02 +00:00
private void pbBoxSlot_MouseDown ( object sender , MouseEventArgs e )
{
2016-08-05 11:04:56 +00:00
if ( e . Button = = MouseButtons . Left )
2016-08-26 01:50:51 +00:00
DragInfo . slotLeftMouseIsDown = true ;
2016-08-05 11:04:56 +00:00
if ( e . Button = = MouseButtons . Right )
2016-08-26 01:50:51 +00:00
DragInfo . slotRightMouseIsDown = true ;
2016-08-05 11:04:56 +00:00
}
private void pbBoxSlot_MouseMove ( object sender , MouseEventArgs e )
{
2016-08-26 01:50:51 +00:00
if ( DragInfo . slotDragDropInProgress )
2014-11-26 04:43:02 +00:00
return ;
2017-01-26 06:51:52 +00:00
if ( ! DragInfo . slotLeftMouseIsDown )
return ;
2015-03-11 01:44:51 +00:00
2017-01-26 06:51:52 +00:00
// The goal is to create a temporary PKX file for the underlying Pokemon
// and use that file to perform a drag drop operation.
2015-03-11 01:44:51 +00:00
2017-01-26 06:51:52 +00:00
// Abort if there is no Pokemon in the given slot.
PictureBox pb = ( PictureBox ) sender ;
if ( pb . Image = = null )
return ;
2016-12-16 07:17:17 +00:00
2017-01-26 06:51:52 +00:00
int slot = getSlot ( pb ) ;
int box = slot > = 30 ? - 1 : CB_BoxSelect . SelectedIndex ;
if ( SAV . getIsSlotLocked ( box , slot ) )
return ;
2015-03-11 01:44:51 +00:00
2017-01-26 06:51:52 +00:00
// Set flag to prevent re-entering.
DragInfo . slotDragDropInProgress = true ;
2016-07-10 17:35:44 +00:00
2017-01-26 06:51:52 +00:00
DragInfo . slotSource = this ;
DragInfo . slotSourceSlotNumber = slot ;
DragInfo . slotSourceBoxNumber = box ;
DragInfo . slotSourceOffset = getPKXOffset ( DragInfo . slotSourceSlotNumber ) ;
2016-08-05 11:04:56 +00:00
2017-01-26 06:51:52 +00:00
// Prepare Data
DragInfo . slotPkmSource = SAV . getData ( DragInfo . slotSourceOffset , SAV . SIZE_STORED ) ;
2016-08-05 11:04:56 +00:00
2017-01-26 06:51:52 +00:00
// 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 fn = pkx . FileName ; fn = fn . Substring ( 0 , fn . LastIndexOf ( '.' ) ) ;
string filename = $"{fn}{(encrypt ? " . ek " + pkx.Format : " . " + pkx.Extension)}" ;
2016-08-26 01:50:51 +00:00
2017-01-26 06:51:52 +00:00
// 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 = 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 . SameBox & & DragInfo . DestinationValid )
2017-02-25 04:26:28 +00:00
{
if ( SAV . getIsTeamSet ( box , DragInfo . slotDestinationSlotNumber ) ^ SAV . getIsTeamSet ( box , DragInfo . slotSourceSlotNumber ) )
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotDestinationSlotNumber ] , SAV . getStoredSlot ( DragInfo . slotDestinationOffset ) ) ;
else
SlotPictureBoxes [ DragInfo . slotDestinationSlotNumber ] . Image = img ;
}
2016-08-05 11:04:56 +00:00
2017-01-26 06:51:52 +00:00
if ( result = = DragDropEffects . Copy ) // viewed in tabs, apply 'view' highlight
getSlotColor ( DragInfo . slotSourceSlotNumber , Resources . slotView ) ;
2016-08-05 11:04:56 +00:00
}
2017-01-26 06:51:52 +00:00
catch ( Exception x )
{
WinFormsUtil . 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 ( ) ;
if ( DragInfo . SourceParty | | DragInfo . DestinationParty )
setParty ( ) ;
2014-11-26 04:43:02 +00:00
}
private void pbBoxSlot_DragDrop ( object sender , DragEventArgs e )
{
2016-09-14 04:17:07 +00:00
DragInfo . slotDestination = this ;
2016-08-26 01:50:51 +00:00
DragInfo . slotDestinationSlotNumber = getSlot ( sender ) ;
DragInfo . slotDestinationOffset = getPKXOffset ( DragInfo . slotDestinationSlotNumber ) ;
2016-12-19 07:49:27 +00:00
DragInfo . slotDestinationBoxNumber = DragInfo . DestinationParty ? - 1 : CB_BoxSelect . SelectedIndex ;
2014-11-26 04:43:02 +00:00
2014-11-30 18:59:10 +00:00
// Check for In-Dropped files (PKX,SAV,ETC)
string [ ] files = ( string [ ] ) e . Data . GetData ( DataFormats . FileDrop ) ;
2014-12-14 04:39:31 +00:00
if ( Directory . Exists ( files [ 0 ] ) ) { loadBoxesFromDB ( files [ 0 ] ) ; return ; }
2016-12-19 07:49:27 +00:00
if ( DragInfo . SameSlot )
return ;
2016-12-16 07:17:17 +00:00
if ( SAV . getIsSlotLocked ( DragInfo . slotDestinationBoxNumber , DragInfo . slotDestinationSlotNumber ) )
{
DragInfo . slotDestinationSlotNumber = - 1 ; // Invalidate
2017-01-08 07:54:09 +00:00
WinFormsUtil . Alert ( "Unable to set to locked slot." ) ;
2016-12-16 07:17:17 +00:00
return ;
}
2016-08-26 01:50:51 +00:00
if ( DragInfo . slotSourceOffset < 0 ) // file
2014-11-30 18:59:10 +00:00
{
2016-06-21 06:02:26 +00:00
if ( files . Length < = 0 )
return ;
string file = files [ 0 ] ;
2016-08-01 03:31:43 +00:00
FileInfo fi = new FileInfo ( file ) ;
2016-08-06 19:57:53 +00:00
if ( ! PKX . getIsPKM ( fi . Length ) & & ! MysteryGift . getIsMysteryGift ( fi . Length ) )
2016-06-30 00:36:03 +00:00
{ openQuick ( file ) ; return ; }
2016-06-21 06:02:26 +00:00
byte [ ] data = File . ReadAllBytes ( file ) ;
2016-08-01 03:31:43 +00:00
MysteryGift mg = MysteryGift . getMysteryGift ( data , fi . Extension ) ;
2017-02-07 06:19:10 +00:00
PKM temp = mg ? . convertToPKM ( SAV ) ? ? PKMConverter . getPKMfromBytes ( data , prefer : fi . Extension . Length > 0 ? ( fi . Extension . Last ( ) - 0x30 ) & 7 : SAV . Generation ) ;
2016-06-21 06:02:26 +00:00
string c ;
2016-06-20 04:22:43 +00:00
2016-09-26 23:14:11 +00:00
PKM pk = PKMConverter . convertToFormat ( temp , SAV . PKMType , out c ) ;
2016-06-21 06:02:26 +00:00
if ( pk = = null )
2017-01-08 07:54:09 +00:00
{ WinFormsUtil . Error ( c ) ; Console . WriteLine ( c ) ; return ; }
2016-06-21 06:02:26 +00:00
2017-02-04 22:58:30 +00:00
string [ ] errata = SAV . IsPKMCompatible ( pk ) ;
2016-06-21 06:02:26 +00:00
if ( errata . Length > 0 )
{
string concat = string . Join ( Environment . NewLine , errata ) ;
2017-01-08 07:54:09 +00:00
if ( DialogResult . Yes ! = WinFormsUtil . Prompt ( MessageBoxButtons . YesNo , concat , "Continue?" ) )
2016-06-21 06:02:26 +00:00
{ Console . WriteLine ( c ) ; Console . WriteLine ( concat ) ; return ; }
2014-11-30 18:59:10 +00:00
}
2016-06-21 06:02:26 +00:00
2016-12-18 03:05:22 +00:00
DragInfo . setPKMtoDestination ( SAV , pk ) ;
2016-08-26 01:50:51 +00:00
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotDestinationSlotNumber ] , pk ) ;
2017-01-14 21:10:36 +00:00
getSlotColor ( DragInfo . slotDestinationSlotNumber , Resources . slotSet ) ;
2016-06-21 06:02:26 +00:00
Console . WriteLine ( c ) ;
2014-11-30 18:59:10 +00:00
}
else
{
2016-12-18 03:05:22 +00:00
PKM pkz = DragInfo . getPKMfromSource ( SAV ) ;
2016-08-30 06:15:27 +00:00
if ( ! DragInfo . SourceValid ) { } // not overwritable, do nothing
else if ( ModifierKeys = = Keys . Alt & & DragInfo . DestinationValid ) // overwrite delete old slot
2014-12-20 19:27:29 +00:00
{
2016-08-26 01:50:51 +00:00
// Clear from slot
if ( DragInfo . SameBox )
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotSourceSlotNumber ] , SAV . BlankPKM ) ; // picturebox
2016-12-18 03:05:22 +00:00
DragInfo . setPKMtoSource ( SAV , SAV . BlankPKM ) ;
2014-12-20 19:27:29 +00:00
}
2016-08-30 06:15:27 +00:00
else if ( ModifierKeys ! = Keys . Control & & DragInfo . DestinationValid )
2014-12-20 19:27:29 +00:00
{
2016-08-26 01:50:51 +00:00
// Load data from destination
PKM pk = ( ( PictureBox ) sender ) . Image ! = null
2016-12-18 03:05:22 +00:00
? DragInfo . getPKMfromDestination ( SAV )
2016-08-26 01:50:51 +00:00
: SAV . BlankPKM ;
2014-12-20 19:27:29 +00:00
2016-08-26 01:50:51 +00:00
// Set destination pokemon image to source picture box
if ( DragInfo . SameBox )
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotSourceSlotNumber ] , pk ) ;
2014-12-20 19:27:29 +00:00
2016-08-26 01:50:51 +00:00
// Set destination pokemon data to source slot
2016-12-18 03:05:22 +00:00
DragInfo . setPKMtoSource ( SAV , pk ) ;
2014-12-20 19:27:29 +00:00
}
2016-08-26 01:50:51 +00:00
else if ( DragInfo . SameBox )
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotSourceSlotNumber ] , pkz ) ;
2016-08-05 11:04:56 +00:00
// Copy from temp to destination slot.
2016-12-18 03:05:22 +00:00
DragInfo . setPKMtoDestination ( SAV , pkz ) ;
2016-08-26 01:50:51 +00:00
getQuickFiller ( SlotPictureBoxes [ DragInfo . slotDestinationSlotNumber ] , pkz ) ;
2014-12-20 22:44:17 +00:00
2016-08-21 16:07:44 +00:00
e . Effect = DragDropEffects . Link ;
2016-08-26 01:50:51 +00:00
Cursor = DefaultCursor ;
2014-11-30 18:59:10 +00:00
}
2016-12-18 03:05:22 +00:00
if ( DragInfo . SourceParty | | DragInfo . DestinationParty )
setParty ( ) ;
2016-09-14 04:17:07 +00:00
if ( DragInfo . slotSource = = null ) // another instance or file
{
notifyBoxViewerRefresh ( ) ;
DragInfo . Reset ( ) ;
}
2014-11-26 04:43:02 +00:00
}
private void pbBoxSlot_DragEnter ( object sender , DragEventArgs e )
{
2015-11-22 19:03:38 +00:00
if ( e . AllowedEffect = = ( DragDropEffects . Copy | DragDropEffects . Link ) ) // external file
e . Effect = DragDropEffects . Copy ;
else if ( e . Data ! = null ) // within
2014-11-26 04:43:02 +00:00
e . Effect = DragDropEffects . Move ;
2016-08-26 01:50:51 +00:00
if ( DragInfo . slotDragDropInProgress )
2017-02-05 07:11:48 +00:00
Cursor = ( Cursor ) DragInfo . Cursor ;
2014-11-26 04:43:02 +00:00
}
2016-08-05 11:04:56 +00:00
private void pbBoxSlot_QueryContinueDrag ( object sender , QueryContinueDragEventArgs e )
{
if ( e . Action = = DragAction . Cancel | | e . Action = = DragAction . Drop )
2016-08-26 01:50:51 +00:00
{
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 ;
2016-09-14 04:17:07 +00:00
public static object slotSource ;
2016-08-26 01:50:51 +00:00
public static int slotSourceOffset = - 1 ;
public static int slotSourceSlotNumber = - 1 ;
public static int slotSourceBoxNumber = - 1 ;
2016-09-14 04:17:07 +00:00
public static object slotDestination ;
2016-08-26 01:50:51 +00:00
public static int slotDestinationOffset = - 1 ;
public static int slotDestinationSlotNumber = - 1 ;
public static int slotDestinationBoxNumber = - 1 ;
2017-02-05 07:11:48 +00:00
public static object Cursor ;
2016-08-26 01:50:51 +00:00
public static string CurrentPath ;
public static bool SameBox = > slotSourceBoxNumber > - 1 & & slotSourceBoxNumber = = slotDestinationBoxNumber ;
2016-12-19 07:49:27 +00:00
public static bool SameSlot = > slotSourceSlotNumber = = slotDestinationSlotNumber & & slotSourceBoxNumber = = slotDestinationBoxNumber ;
2016-12-27 02:22:45 +00:00
public static bool SourceValid = > slotSourceSlotNumber > - 1 & & ( slotSourceBoxNumber > - 1 | | SourceParty ) ;
public static bool DestinationValid = > slotDestinationSlotNumber > - 1 & & ( slotDestinationBoxNumber > - 1 | | DestinationParty ) ;
2016-12-18 03:05:22 +00:00
public static bool SourceParty = > 30 < = slotSourceSlotNumber & & slotSourceSlotNumber < 36 ;
public static bool DestinationParty = > 30 < = slotDestinationSlotNumber & & slotDestinationSlotNumber < 36 ;
// PKM Get Set
public static PKM getPKMfromSource ( SaveFile SAV )
{
int o = slotSourceOffset ;
return SourceParty ? SAV . getPartySlot ( o ) : SAV . getStoredSlot ( o ) ;
}
public static PKM getPKMfromDestination ( SaveFile SAV )
{
int o = slotDestinationOffset ;
return DestinationParty ? SAV . getPartySlot ( o ) : SAV . getStoredSlot ( o ) ;
}
public static void setPKMtoSource ( SaveFile SAV , PKM pk )
{
int o = slotSourceOffset ;
if ( ! SourceParty )
{ SAV . setStoredSlot ( pk , o ) ; return ; }
if ( pk . Species = = 0 ) // Empty Slot
{ SAV . deletePartySlot ( slotSourceSlotNumber - 30 ) ; return ; }
if ( pk . Stat_HPMax = = 0 ) // Without Stats (Box)
2016-12-23 06:03:32 +00:00
{
2016-12-18 08:15:36 +00:00
pk . setStats ( pk . getStats ( SAV . Personal . getFormeEntry ( pk . Species , pk . AltForm ) ) ) ;
2016-12-23 06:03:32 +00:00
pk . Stat_Level = pk . CurrentLevel ;
}
2016-12-18 03:05:22 +00:00
SAV . setPartySlot ( pk , o ) ;
}
public static void setPKMtoDestination ( SaveFile SAV , PKM pk )
{
int o = slotDestinationOffset ;
if ( ! DestinationParty )
{ SAV . setStoredSlot ( pk , o ) ; return ; }
if ( 30 + SAV . PartyCount < slotDestinationSlotNumber )
{
o = SAV . getPartyOffset ( SAV . PartyCount ) ;
slotDestinationSlotNumber = 30 + SAV . PartyCount ;
}
if ( pk . Stat_HPMax = = 0 ) // Without Stats (Box/File)
2016-12-23 06:03:32 +00:00
{
2016-12-18 08:15:36 +00:00
pk . setStats ( pk . getStats ( SAV . Personal . getFormeEntry ( pk . Species , pk . AltForm ) ) ) ;
2016-12-23 06:03:32 +00:00
pk . Stat_Level = pk . CurrentLevel ;
}
2016-12-18 03:05:22 +00:00
SAV . setPartySlot ( pk , o ) ;
}
2016-08-26 01:50:51 +00:00
public static void Reset ( )
2016-08-05 11:04:56 +00:00
{
slotLeftMouseIsDown = false ;
slotRightMouseIsDown = false ;
slotDragDropInProgress = false ;
2016-08-26 01:50:51 +00:00
slotPkmSource = null ;
slotSourceOffset = slotSourceSlotNumber = slotSourceBoxNumber = - 1 ;
slotPkmDestination = null ;
slotDestinationOffset = slotSourceBoxNumber = slotDestinationBoxNumber = - 1 ;
Cursor = null ;
CurrentPath = null ;
2016-09-14 04:17:07 +00:00
slotSource = null ;
slotDestination = null ;
}
public static bool? WasDragParticipant ( object form , int index )
{
2016-12-11 21:48:26 +00:00
if ( slotDestinationBoxNumber ! = index & & slotSourceBoxNumber ! = index )
2016-09-14 04:17:07 +00:00
return null ; // form was not watching box
return slotSource = = form | | slotDestination = = form ; // form already updated?
2016-08-05 11:04:56 +00:00
}
}
2016-06-20 04:22:43 +00:00
2014-12-13 22:48:34 +00:00
#endregion
2014-06-28 21:22:05 +00:00
}
2015-03-03 17:11:21 +00:00
}