mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 22:54:14 +00:00
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:
parent
9e7a4d01ab
commit
9085dfd950
4 changed files with 69 additions and 13 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue