Allow backwards conversion on hax

works somewhat on drag&drop individual files, not guaranteed to work for
all pkm formats
https://i.imgur.com/v3i3ON9.png

Closes #1792
This commit is contained in:
Kurt 2018-01-28 22:47:03 -08:00
parent 9e7a4d01ab
commit 9085dfd950
4 changed files with 69 additions and 13 deletions

View file

@ -964,10 +964,10 @@ namespace PKHeX.Core
// Only transfer declared properties not defined in PKM.cs but in the actual type
var SourceProperties = ReflectUtil.GetPropertiesCanWritePublicDeclared(Source.GetType());
var DestinationProperties = ReflectUtil.GetPropertiesCanWritePublicDeclared(Destination.GetType());
foreach (string property in SourceProperties.Intersect(DestinationProperties))
foreach (string property in SourceProperties.Intersect(DestinationProperties).Reverse())
{
var prop = ReflectUtil.GetValue(this, property);
if (prop != null)
if (prop != null && !(prop is byte[]))
ReflectUtil.SetValue(Destination, property, prop);
}
}

View file

@ -16,6 +16,7 @@ namespace PKHeX.Core
public static string OT_Name { get; private set; } = "PKHeX";
public static int OT_Gender { get; private set; } // Male
public static int Language { get; private set; } = 1; // en
public static bool AllowIncompatibleConversion { private get; set; }
public static void UpdateConfig(int SUBREGION, int COUNTRY, int _3DSREGION, string TRAINERNAME, int TRAINERGENDER, int LANGUAGE)
{
@ -213,6 +214,21 @@ namespace PKHeX.Core
return pk;
}
var pkm = ConvertPKM(pk, PKMType, fromType, out comment);
if (!AllowIncompatibleConversion || pkm != null)
return pkm;
// Try Incompatible Conversion
pkm = GetBlank(PKMType);
TransferProperties(pk, pkm);
if (!SaveUtil.IsPKMCompatibleWithModifications(pkm))
return null;
comment = "Converted via reflection.";
return pkm;
}
private static PKM ConvertPKM(PKM pk, Type PKMType, Type fromType, out string comment)
{
if (IsNotTransferrable(pk, out comment))
return null;
@ -226,6 +242,17 @@ namespace PKHeX.Core
return null;
}
var pkm = ConvertPKM(pk, PKMType, fromType, toFormat, ref comment);
comment = pkm == null
? $"Cannot convert a {fromType.Name} to a {PKMType.Name}."
: $"Converted from {fromType.Name} to {PKMType.Name}.";
return pkm;
}
private static PKM ConvertPKM(PKM pk, Type PKMType, Type fromType, int toFormat, ref string comment)
{
PKM pkm = pk.Clone();
if (pkm.IsEgg)
ForceHatchPKM(pkm);
@ -246,7 +273,7 @@ namespace PKHeX.Core
if (pk.Species > 151)
{
comment = $"Cannot convert a {PKX.GetSpeciesName(pkm.Species, pkm.Japanese ? 1 : 2)} to {PKMType.Name}";
return null;
return pkm;
}
pkm = ((PK2)pk).ConvertToPK1();
pkm.ClearInvalidMoves();
@ -295,7 +322,7 @@ namespace PKHeX.Core
if (pkm.Species == 25 && pkm.AltForm != 0) // cosplay pikachu
{
comment = "Cannot transfer Cosplay Pikachu forward.";
return null;
return pkm;
}
pkm = ((PK6) pkm).ConvertToPK7();
if (toFormat == 7)
@ -304,11 +331,6 @@ namespace PKHeX.Core
case nameof(PK7):
break;
}
comment = pkm == null
? $"Cannot convert a {fromType.Name} to a {PKMType.Name}."
: $"Converted from {fromType.Name} to {PKMType.Name}.";
return pkm;
}
@ -426,7 +448,8 @@ namespace PKHeX.Core
{
pkm = null;
c = $"Can't load {pk.GetType().Name}s to Gen{target.Format} saves.";
return false;
if (!AllowIncompatibleConversion)
return false;
}
if (target.Format < 3 && pk.Japanese != target.Japanese)
{
@ -434,7 +457,8 @@ namespace PKHeX.Core
var strs = new[] { "International", "Japanese" };
var val = target.Japanese ? 0 : 1;
c = $"Cannot load {strs[val]} {pk.GetType().Name}s to {strs[val ^ 1]} saves.";
return false;
if (!AllowIncompatibleConversion)
return false;
}
pkm = ConvertToType(pk, target.GetType(), out c);
Debug.WriteLine(c);

View file

@ -1132,11 +1132,38 @@ namespace PKHeX.Core
pk.ClearInvalidMoves();
if (pk.EVs.Any(ev => ev > SAV.MaxEV))
pk.EVs = pk.EVs.Select(ev => Math.Min(SAV.MaxEV, ev)).ToArray();
if (pk.IVs.Any(ev => ev > SAV.MaxEV))
if (pk.IVs.Any(iv => iv > SAV.MaxIV))
pk.IVs = pk.IVs.Select(iv => Math.Min(SAV.MaxIV, iv)).ToArray();
return true;
}
/// <summary>
/// Checks if the <see cref="PKM"/> is compatible with the input <see cref="PKM"/>, and makes any necessary modifications to force compatibility.
/// </summary>
/// <remarks>Should only be used when forcing a backwards conversion to sanitize the PKM fields to the target format.
/// If the PKM is compatible, some properties may be forced to sanitized values.</remarks>
/// <param name="pk">PKM input that is to be sanity checked.</param>
/// <returns>Indication whether or not the PKM is compatible.</returns>
public static bool IsPKMCompatibleWithModifications(PKM pk)
{
if (pk.Species > pk.MaxSpeciesID)
return false;
if (pk.HeldItem > pk.MaxItemID)
pk.HeldItem = 0;
if (pk.Nickname.Length > pk.NickLength)
pk.Nickname = pk.Nickname.Substring(0, pk.NickLength);
if (pk.OT_Name.Length > pk.OTLength)
pk.OT_Name = pk.OT_Name.Substring(0, pk.OTLength);
if (pk.Moves.Any(move => move > pk.MaxMoveID))
pk.ClearInvalidMoves();
if (pk.EVs.Any(ev => ev > pk.MaxEV))
pk.EVs = pk.EVs.Select(ev => Math.Min(pk.MaxEV, ev)).ToArray();
if (pk.IVs.Any(iv => iv > pk.MaxIV))
pk.IVs = pk.IVs.Select(iv => Math.Min(pk.MaxIV, iv)).ToArray();
return true;
}
/// <summary>
/// Sets the details of a path to a <see cref="SaveFile"/> object.

View file

@ -39,7 +39,10 @@ namespace PKHeX.WinForms
Show();
WindowState = FormWindowState.Normal;
if (HaX)
{
PKMConverter.AllowIncompatibleConversion = true;
WinFormsUtil.Alert("Illegal mode activated.", "Please behave.");
}
else if (showChangelog)
new About().ShowDialog();
@ -100,8 +103,10 @@ namespace PKHeX.WinForms
BAKprompt = false;
CB_MainLanguage.Items.AddRange(main_langlist);
C_SAV.HaX = PKME_Tabs.HaX = HaX = args.Any(x => string.Equals(x.Trim('-'), nameof(HaX), StringComparison.CurrentCultureIgnoreCase))
HaX = args.Any(x => string.Equals(x.Trim('-'), nameof(HaX), StringComparison.CurrentCultureIgnoreCase))
|| Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().MainModule.FileName).EndsWith(nameof(HaX));
PKMConverter.AllowIncompatibleConversion = C_SAV.HaX = PKME_Tabs.HaX = HaX;
PB_Legal.Visible = !HaX;
int languageID = 1; // English