Add C/XD transferring

reflection is neat

when making c/xd format, recalculate stats
This commit is contained in:
Kaphotics 2016-10-02 10:18:31 -07:00
parent 503452e1c6
commit 4ce29b392d
7 changed files with 98 additions and 40 deletions

View file

@ -437,21 +437,19 @@ namespace PKHeX
public PK4 convertToPK4()
{
PK4 pk4 = new PK4();
foreach (string property in ReflectUtil.getPropertiesCanWritePublic(typeof(PK4)).Intersect(ReflectUtil.getPropertiesCanWritePublic(typeof(BK4))))
{
var prop = ReflectUtil.GetValue(this, property);
if (prop != null)
ReflectUtil.SetValue(pk4, property, prop);
}
TransferPropertiesWithReflection(this, pk4);
// Fix Non-Reflectable properties
Array.Copy(Data, 0x78, pk4.Data, 0x78, 6); // Met Info
// Preserve Trash Bytes
for (int i = 0; i < 11; i++) // Nickname
{
Data.Skip(0x48 + 2 * i).Take(2).Reverse().ToArray().CopyTo(pk4.Data, 0x48 + 2 * i);
pk4.Data[0x48 + 2*i] = Data[0x48 + 2*i + 1];
pk4.Data[0x48 + 2*i + 1] = Data[0x48 + 2*i];
}
for (int i = 0; i < 8; i++) // OT_Name
{
Data.Skip(0x68 + 2 * i).Take(2).Reverse().ToArray().CopyTo(pk4.Data, 0x68 + 2 * i);
pk4.Data[0x68 + 2*i] = Data[0x68 + 2*i + 1];
pk4.Data[0x68 + 2*i + 1] = Data[0x68 + 2*i];
}
pk4.Sanity = 0;
pk4.RefreshChecksum();

View file

@ -167,7 +167,7 @@ namespace PKHeX
public override int PKRS_Strain { get { return Data[0xCA] & 0xF; } set { Data[0xCA] = (byte)(value & 0xF); } }
public override bool IsEgg { get { return Data[0xCB] == 1; } set { Data[0xCB] = (byte)(value ? 1 : 0); } }
public int AbilityNumber { get { return Data[0xCC]; } set { Data[0xCC] = (byte)(value & 1); } }
public override bool Valid => Data[0xCD] == 0;
public override bool Valid { get { return Data[0xCD] == 0; } set { if (value) Data[0xCD] = 0; } }
// 0xCE unknown
public override byte MarkByte { get { return Data[0xCF]; } protected set { Data[0xCF] = value; } }
public override int PKRS_Days { get { return Math.Max((sbyte)Data[0xD0], (sbyte)0); } set { Data[0xD0] = (byte)(value == 0 ? 0xFF : value & 0xF); } }

View file

@ -408,21 +408,19 @@ namespace PKHeX
public BK4 convertToBK4()
{
BK4 bk4 = new BK4();
foreach (string property in ReflectUtil.getPropertiesCanWritePublic(typeof(PK4)).Intersect(ReflectUtil.getPropertiesCanWritePublic(typeof(BK4))))
{
var prop = ReflectUtil.GetValue(this, property);
if (prop != null)
ReflectUtil.SetValue(bk4, property, prop);
}
TransferPropertiesWithReflection(this, bk4);
// Fix Non-Reflectable properties
Array.Copy(Data, 0x78, bk4.Data, 0x78, 6); // Met Info
// Preserve Trash Bytes
for (int i = 0; i < 11; i++) // Nickname
{
Data.Skip(0x48 + 2*i).Take(2).Reverse().ToArray().CopyTo(bk4.Data, 0x48 + 2*i);
bk4.Data[0x48 + 2*i] = Data[0x48 + 2*i + 1];
bk4.Data[0x48 + 2*i + 1] = Data[0x48 + 2*i];
}
for (int i = 0; i < 8; i++) // OT_Name
{
Data.Skip(0x68 + 2 * i).Take(2).Reverse().ToArray().CopyTo(bk4.Data, 0x68 + 2 * i);
bk4.Data[0x68 + 2*i] = Data[0x68 + 2*i + 1];
bk4.Data[0x68 + 2*i + 1] = Data[0x68 + 2*i];
}
bk4.Sanity = 0x4000;
bk4.RefreshChecksum();

View file

@ -20,8 +20,8 @@ namespace PKHeX
public virtual byte[] EncryptedBoxData => Encrypt().Take(SIZE_STORED).ToArray();
public virtual byte[] DecryptedPartyData => Write().Take(SIZE_PARTY).ToArray();
public virtual byte[] DecryptedBoxData => Write().Take(SIZE_STORED).ToArray();
public virtual bool Valid => ChecksumValid && Sanity == 0;
public virtual bool Valid { get { return ChecksumValid && Sanity == 0; } set { if (!value) return; Sanity = 0; RefreshChecksum(); } }
protected virtual ushort CalculateChecksum()
{
ushort chk = 0;
@ -483,5 +483,53 @@ namespace PKHeX
{
do PID = Util.rnd32(); while (PKX.getUnownForm(PID) != form);
}
// Gen3 Conversion -- do not use if format > 4
public PKM convertToCK3()
{
if (Format != 3)
return null;
if (GetType() == typeof(CK3))
return this;
var pk = new CK3();
TransferPropertiesWithReflection(this, pk);
pk.setStats(getStats(PersonalTable.RS[pk.Species]));
return pk;
}
public PKM convertToXK3()
{
if (Format != 3)
return null;
if (GetType() == typeof(XK3))
return this;
var pk = new XK3();
TransferPropertiesWithReflection(this, pk);
pk.setStats(getStats(PersonalTable.RS[pk.Species]));
return pk;
}
public PKM convertToPK3()
{
if (Format != 3)
return null;
if (GetType() == typeof(PK3))
return this;
var pk = new PK3();
TransferPropertiesWithReflection(this, pk);
pk.RefreshChecksum();
return pk;
}
protected void TransferPropertiesWithReflection(PKM Source, PKM Destination)
{
var SourceProperties = ReflectUtil.getPropertiesCanWritePublic(Source.GetType());
var DestinationProperties = ReflectUtil.getPropertiesCanWritePublic(Destination.GetType());
foreach (string property in SourceProperties.Intersect(DestinationProperties).Where(prop => prop != nameof(Data)))
{
var prop = ReflectUtil.GetValue(this, property);
if (prop == null)
continue;
ReflectUtil.SetValue(Destination, property, prop);
}
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Linq;
namespace PKHeX
@ -41,6 +40,8 @@ namespace PKHeX
return 2;
case PKX.SIZE_3PARTY:
case PKX.SIZE_3STORED:
case PKX.SIZE_3CSTORED:
case PKX.SIZE_3XSTORED:
return 3;
case PKX.SIZE_4PARTY:
case PKX.SIZE_4STORED:
@ -89,7 +90,11 @@ namespace PKHeX
PL2[0].Identifier = ident;
return PL2[0];
case 3:
return new PK3(data, ident);
switch (data.Length) {
case PKX.SIZE_3CSTORED: return new CK3(data, ident);
case PKX.SIZE_3XSTORED: return new XK3(data, ident);
default: return new PK3(data, ident);
}
case 4:
var pk = new PK4(data, ident);
if (!pk.Valid || pk.Sanity != 0)
@ -149,7 +154,7 @@ namespace PKHeX
{
if (pk.Species > 151)
{
comment = $"Cannot convert a {PKX.getSpeciesName(pk.Species, ((PK2)pk).Japanese ? 1 : 2)} to {PKMType.Name}";
comment = $"Cannot convert a {PKX.getSpeciesName(pkm.Species, ((PK2)pkm).Japanese ? 1 : 2)} to {PKMType.Name}";
return null;
}
pkm = ((PK2)pk).convertToPK1();
@ -158,18 +163,29 @@ namespace PKHeX
pkm = null;
break;
case "PK2":
if (PKMType == typeof(PK1))
{
pkm = ((PK1)pk).convertToPK2();
}
else
pkm = null;
pkm = PKMType == typeof(PK1) ? ((PK1)pkm).convertToPK2() : null;
break;
case "CK3":
case "XK3":
// interconverting C/XD needs to visit main series format
// ends up stripping purification/shadow etc stats
pkm = pkm.convertToPK3();
goto case "PK3"; // fall through
case "PK3":
if (toFormat == 3)
if (toFormat == 3) // Gen3 Inter-trading
{
// Colo/XD stuff here!
switch (PKMType.Name)
{
case "CK3": pkm = pkm.convertToCK3(); break;
case "XK3": pkm = pkm.convertToXK3(); break;
case "PK3": pkm = pkm.convertToPK3(); break; // already converted, instantly returns
default: throw new FormatException();
}
break;
}
if (fromType.Name != "PK3")
pkm = pkm.convertToPK3();
pkm = ((PK3)pkm).convertToPK4();
if (toFormat == 4)
{
@ -210,14 +226,11 @@ namespace PKHeX
break;
}
}
if (pkm == null)
{
comment = $"Cannot convert a {fromType.Name} to a {PKMType.Name}.";
}
else
{
comment = $"Converted from {fromType.Name} to {PKMType.Name}.";
}
comment = pkm == null
? $"Cannot convert a {fromType.Name} to a {PKMType.Name}."
: $"Converted from {fromType.Name} to {PKMType.Name}.";
return pkm;
}
internal static void checkEncrypted(ref byte[] pkm)

View file

@ -51,6 +51,7 @@ namespace PKHeX
SIZE_1JLIST, SIZE_1ULIST,
SIZE_2ULIST, SIZE_2JLIST,
SIZE_3STORED, SIZE_3PARTY,
SIZE_3CSTORED, SIZE_3XSTORED,
SIZE_4STORED, SIZE_4PARTY,
SIZE_5PARTY,
SIZE_6STORED, SIZE_6PARTY

View file

@ -65,8 +65,8 @@ namespace PKHeX
public bool CapturedFlag { get { return (XDPKMFLAGS & (1 << 2)) == 1 << 2; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 2) | (value ? 1 << 2 : 0); } }
public bool UnusedFlag3 { get { return (XDPKMFLAGS & (1 << 3)) == 1 << 3; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 3) | (value ? 1 << 3 : 0); } }
public bool BlockTrades { get { return (XDPKMFLAGS & (1 << 4)) == 1 << 4; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 4) | (value ? 1 << 4 : 0); } }
public override bool Valid => (XDPKMFLAGS & (1 << 5)) == 0; // invalid flag not set
public int AbilityNumber { get { return (XDPKMFLAGS >> 6) & 1; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (value << 6); } }
public override bool Valid { get { return (XDPKMFLAGS & (1 << 5)) == 0; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 5) | (value ? 0 : 1 << 5); } } // invalid flag
public int AbilityNumber { get { return (XDPKMFLAGS >> 6) & 1; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 6) | (value << 6); } }
public override bool IsEgg { get { return (XDPKMFLAGS & (1 << 7)) == 1 << 7; } set { XDPKMFLAGS = XDPKMFLAGS & ~(1 << 7) | (value ? 1 << 7 : 0); } }
// 0x1E-0x1F Unknown
public override uint EXP { get { return BigEndian.ToUInt32(Data, 0x20); } set { BigEndian.GetBytes(value).CopyTo(Data, 0x20); } }