mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
Add C/XD transferring
reflection is neat when making c/xd format, recalculate stats
This commit is contained in:
parent
503452e1c6
commit
4ce29b392d
7 changed files with 98 additions and 40 deletions
|
@ -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();
|
||||
|
|
|
@ -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); } }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); } }
|
||||
|
|
Loading…
Add table
Reference in a new issue