diff --git a/PKHeX.Core/PKM/CK3.cs b/PKHeX.Core/PKM/CK3.cs
index 5f84e18eb..7d18a2f23 100644
--- a/PKHeX.Core/PKM/CK3.cs
+++ b/PKHeX.Core/PKM/CK3.cs
@@ -3,7 +3,7 @@
namespace PKHeX.Core
{
/// Generation 3 format, exclusively for Pokémon Colosseum.
- public sealed class CK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3, IShadowPKM
+ public sealed class CK3 : _K3, IShadowPKM
{
public static readonly byte[] ExtraBytes =
{
@@ -26,6 +26,7 @@ public CK3(byte[] decryptedData = null, string ident = null)
if (Data.Length != SIZE_PARTY)
Array.Resize(ref Data, SIZE_PARTY);
}
+ public CK3() => Data = new byte[SIZE_PARTY];
public override PKM Clone() => new CK3((byte[])Data.Clone(), Identifier);
private string GetString(int Offset, int Count) => StringConverter.GetBEString3(Data, Offset, Count);
@@ -36,17 +37,6 @@ public CK3(byte[] decryptedData = null, string ident = null)
public override byte[] OT_Trash { get => GetData(0x18, 20); set { if (value?.Length == 20) value.CopyTo(Data, 0x18); } }
// Future Attributes
- public override uint EncryptionConstant { get => PID; set { } }
- public override int Nature { get => (int)(PID % 25); set { } }
- public override int AltForm { get => Species == 201 ? PKX.GetUnownForm(PID) : 0; set { } }
-
- public override bool IsNicknamed { get => PKX.IsNicknamedAnyLanguage(Species, Nickname, Format); set { } }
- public override int Gender { get => PKX.GetGenderFromPID(Species, PID); set { } }
- public override int Characteristic => -1;
- public override int CurrentFriendship { get => OT_Friendship; set => OT_Friendship = value; }
- public override int Ability { get { int[] abils = PersonalTable.RS.GetAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } }
- public override int CurrentHandler { get => 0; set { } }
- public override int Egg_Location { get => 0; set { } }
// Silly Attributes
public override ushort Sanity { get => 0; set { } } // valid flag set in pkm structure.
@@ -149,30 +139,30 @@ public CK3(byte[] decryptedData = null, string ident = null)
public override int CNT_Cute { get => Data[0xB4]; set => Data[0xB4] = (byte)value; }
public override int CNT_Smart { get => Data[0xB5]; set => Data[0xB5] = (byte)value; }
public override int CNT_Tough { get => Data[0xB6]; set => Data[0xB6] = (byte)value; }
- public int RibbonCountG3Cool { get => Data[0xB7]; set => Data[0xB7] = (byte)value; }
- public int RibbonCountG3Beauty { get => Data[0xB8]; set => Data[0xB8] = (byte)value; }
- public int RibbonCountG3Cute { get => Data[0xB9]; set => Data[0xB9] = (byte)value; }
- public int RibbonCountG3Smart { get => Data[0xBA]; set => Data[0xBA] = (byte)value; }
- public int RibbonCountG3Tough { get => Data[0xBB]; set => Data[0xBB] = (byte)value; }
+ public override int RibbonCountG3Cool { get => Data[0xB7]; set => Data[0xB7] = (byte)value; }
+ public override int RibbonCountG3Beauty { get => Data[0xB8]; set => Data[0xB8] = (byte)value; }
+ public override int RibbonCountG3Cute { get => Data[0xB9]; set => Data[0xB9] = (byte)value; }
+ public override int RibbonCountG3Smart { get => Data[0xBA]; set => Data[0xBA] = (byte)value; }
+ public override int RibbonCountG3Tough { get => Data[0xBB]; set => Data[0xBB] = (byte)value; }
public override int CNT_Sheen { get => Data[0xBC]; set => Data[0xBC] = (byte)value; }
// Ribbons
- public bool RibbonChampionG3Hoenn { get => Data[0xBD] == 1; set => Data[0xBD] = (byte)(value ? 1 : 0); }
- public bool RibbonWinning { get => Data[0xBE] == 1; set => Data[0xBE] = (byte)(value ? 1 : 0); }
- public bool RibbonVictory { get => Data[0xBF] == 1; set => Data[0xBF] = (byte)(value ? 1 : 0); }
- public bool RibbonArtist { get => Data[0xC0] == 1; set => Data[0xC0] = (byte)(value ? 1 : 0); }
- public bool RibbonEffort { get => Data[0xC1] == 1; set => Data[0xC1] = (byte)(value ? 1 : 0); }
- public bool RibbonChampionBattle { get => Data[0xC2] == 1; set => Data[0xC2] = (byte)(value ? 1 : 0); }
- public bool RibbonChampionRegional { get => Data[0xC3] == 1; set => Data[0xC3] = (byte)(value ? 1 : 0); }
- public bool RibbonChampionNational { get => Data[0xC4] == 1; set => Data[0xC4] = (byte)(value ? 1 : 0); }
- public bool RibbonCountry { get => Data[0xC5] == 1; set => Data[0xC5] = (byte)(value ? 1 : 0); }
- public bool RibbonNational { get => Data[0xC6] == 1; set => Data[0xC6] = (byte)(value ? 1 : 0); }
- public bool RibbonEarth { get => Data[0xC7] == 1; set => Data[0xC7] = (byte)(value ? 1 : 0); }
- public bool RibbonWorld { get => Data[0xC8] == 1; set => Data[0xC8] = (byte)(value ? 1 : 0); }
- public bool Unused1 { get => ((Data[0xC9] >> 0) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~1 | (value ? 1 : 0)); }
- public bool Unused2 { get => ((Data[0xC9] >> 1) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~2 | (value ? 2 : 0)); }
- public bool Unused3 { get => ((Data[0xC9] >> 2) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~4 | (value ? 4 : 0)); }
- public bool Unused4 { get => ((Data[0xC9] >> 3) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~8 | (value ? 8 : 0)); }
+ public override bool RibbonChampionG3Hoenn { get => Data[0xBD] == 1; set => Data[0xBD] = (byte)(value ? 1 : 0); }
+ public override bool RibbonWinning { get => Data[0xBE] == 1; set => Data[0xBE] = (byte)(value ? 1 : 0); }
+ public override bool RibbonVictory { get => Data[0xBF] == 1; set => Data[0xBF] = (byte)(value ? 1 : 0); }
+ public override bool RibbonArtist { get => Data[0xC0] == 1; set => Data[0xC0] = (byte)(value ? 1 : 0); }
+ public override bool RibbonEffort { get => Data[0xC1] == 1; set => Data[0xC1] = (byte)(value ? 1 : 0); }
+ public override bool RibbonChampionBattle { get => Data[0xC2] == 1; set => Data[0xC2] = (byte)(value ? 1 : 0); }
+ public override bool RibbonChampionRegional { get => Data[0xC3] == 1; set => Data[0xC3] = (byte)(value ? 1 : 0); }
+ public override bool RibbonChampionNational { get => Data[0xC4] == 1; set => Data[0xC4] = (byte)(value ? 1 : 0); }
+ public override bool RibbonCountry { get => Data[0xC5] == 1; set => Data[0xC5] = (byte)(value ? 1 : 0); }
+ public override bool RibbonNational { get => Data[0xC6] == 1; set => Data[0xC6] = (byte)(value ? 1 : 0); }
+ public override bool RibbonEarth { get => Data[0xC7] == 1; set => Data[0xC7] = (byte)(value ? 1 : 0); }
+ public override bool RibbonWorld { get => Data[0xC8] == 1; set => Data[0xC8] = (byte)(value ? 1 : 0); }
+ public override bool Unused1 { get => ((Data[0xC9] >> 0) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~1 | (value ? 1 : 0)); }
+ public override bool Unused2 { get => ((Data[0xC9] >> 1) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~2 | (value ? 2 : 0)); }
+ public override bool Unused3 { get => ((Data[0xC9] >> 2) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~4 | (value ? 4 : 0)); }
+ public override bool Unused4 { get => ((Data[0xC9] >> 3) & 1) == 1; set => Data[0xC9] = (byte)(Data[0xC9] & ~8 | (value ? 8 : 0)); }
public override int PKRS_Strain { get => Data[0xCA] & 0xF; set => Data[0xCA] = (byte)(value & 0xF); }
public override bool IsEgg { get => Data[0xCB] == 1; set => Data[0xCB] = (byte)(value ? 1 : 0); }
@@ -187,26 +177,15 @@ public CK3(byte[] decryptedData = null, string ident = null)
public override bool FatefulEncounter { get => Data[0x11C] == 1; set => Data[0x11C] = (byte)(value ? 1 : 0); }
public new int EncounterType { get => Data[0xFB]; set => Data[0xFB] = (byte)value; }
- // Generated Attributes
- public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3);
- public override int TSV => (TID ^ SID) >> 3;
- public override bool Japanese => Language == (int)LanguageID.Japanese;
-
protected override byte[] Encrypt()
{
return (byte[])Data.Clone();
}
-
- // Maximums
- public override int MaxMoveID => Legal.MaxMoveID_3;
- public override int MaxSpeciesID => Legal.MaxSpeciesID_3;
- public override int MaxAbilityID => Legal.MaxAbilityID_3;
- public override int MaxItemID => Legal.MaxItemID_3;
- public override int MaxBallID => Legal.MaxBallID_3;
- public override int MaxGameID => Legal.MaxGameID_3;
- public override int MaxIV => 31;
- public override int MaxEV => 252;
- public override int OTLength => 7;
- public override int NickLength => 10;
+ public PK3 ConvertToPK3()
+ {
+ var pk = ConvertTo();
+ pk.RefreshChecksum();
+ return pk;
+ }
}
}
diff --git a/PKHeX.Core/PKM/PK3.cs b/PKHeX.Core/PKM/PK3.cs
index 75bf6383e..463a0420d 100644
--- a/PKHeX.Core/PKM/PK3.cs
+++ b/PKHeX.Core/PKM/PK3.cs
@@ -3,7 +3,7 @@
namespace PKHeX.Core
{
/// Generation 3 format.
- public sealed class PK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3
+ public sealed class PK3 : _K3
{
public static readonly byte[] ExtraBytes =
{
@@ -22,6 +22,7 @@ public PK3(byte[] decryptedData = null, string ident = null)
if (Data.Length != SIZE_PARTY)
Array.Resize(ref Data, SIZE_PARTY);
}
+ public PK3() => Data = new byte[SIZE_PARTY];
public override PKM Clone() => new PK3((byte[])Data.Clone(), Identifier);
private string GetString(int Offset, int Count) => StringConverter.GetString3(Data, Offset, Count, Japanese);
@@ -31,25 +32,16 @@ public PK3(byte[] decryptedData = null, string ident = null)
public override byte[] Nickname_Trash { get => GetData(0x08, 10); set { if (value?.Length == 10) value.CopyTo(Data, 0x08); } }
public override byte[] OT_Trash { get => GetData(0x14, 7); set { if (value?.Length == 7) value.CopyTo(Data, 0x14); } }
- // Future Attributes
- public override uint EncryptionConstant { get => PID; set { } }
- public override int Nature { get => (int)(PID % 25); set { } }
- public override int AltForm { get => Species == 201 ? PKX.GetUnownForm(PID) : 0; set { } }
-
- public override bool IsNicknamed { get => PKX.IsNicknamedAnyLanguage(Species, Nickname, Format); set { } }
- public override int Gender { get => PKX.GetGenderFromPID(Species, PID); set { } }
- public override int Characteristic => -1;
- public override int CurrentFriendship { get => OT_Friendship; set => OT_Friendship = value; }
- public override int Ability { get { int[] abils = PersonalInfo.Abilities; return abils[AbilityBit && abils[1] != 0 ? 1 : 0]; } set { } }
- public override int CurrentHandler { get => 0; set { } }
- public override int Egg_Location { get => 0; set { } }
+ // At top for System.Reflection execution order hack
+ public override bool IsEgg { get => egg; set => egg = value; }
+ public override int Language { get => lang; set => lang = value; }
// 0x20 Intro
public override uint PID { get => BitConverter.ToUInt32(Data, 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, 0x00); }
public override int TID { get => BitConverter.ToUInt16(Data, 0x04); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x04); }
public override int SID { get => BitConverter.ToUInt16(Data, 0x06); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x06); }
public override string Nickname { get => GetString(0x08, 10); set => SetString(IsEgg ? "タマゴ" : value, 10).CopyTo(Data, 0x08); }
- public override int Language { get => BitConverter.ToUInt16(Data, 0x12) & 0xFF; set => BitConverter.GetBytes((ushort)(IsEgg ? 0x601 : value | 0x200)).CopyTo(Data, 0x12); }
+ private int lang{ get => BitConverter.ToUInt16(Data, 0x12) & 0xFF; set => BitConverter.GetBytes((ushort)(IsEgg ? 0x601 : value | 0x200)).CopyTo(Data, 0x12); }
public override string OT_Name { get => GetString(0x14, 7); set => SetString(value, 7).CopyTo(Data, 0x14); }
public override int MarkValue { get => SwapBits(Data[0x1B], 1, 2); protected set => Data[0x1B] = (byte)SwapBits(value, 1, 2); }
public override ushort Checksum { get => BitConverter.ToUInt16(Data, 0x1C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x1C); }
@@ -115,35 +107,36 @@ public PK3(byte[] decryptedData = null, string ident = null)
public override int IV_SPE { get => (int)(IV32 >> 15) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 15)) | (uint)((value > 31 ? 31 : value) << 15)); }
public override int IV_SPA { get => (int)(IV32 >> 20) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 20)) | (uint)((value > 31 ? 31 : value) << 20)); }
public override int IV_SPD { get => (int)(IV32 >> 25) & 0x1F; set => IV32 = (uint)((IV32 & ~(0x1F << 25)) | (uint)((value > 31 ? 31 : value) << 25)); }
- public override bool IsEgg { get => ((IV32 >> 30) & 1) == 1; set => IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); }
+ private bool egg { get => ((IV32 >> 30) & 1) == 1; set => IV32 = (uint)((IV32 & ~0x40000000) | (uint)(value ? 0x40000000 : 0)); }
public bool AbilityBit { get => IV32 >> 31 == 1; set => IV32 = (IV32 & 0x7FFFFFFF) | (uint)(value ? 1 << 31 : 0); }
private uint RIB0 { get => BitConverter.ToUInt32(Data, 0x4C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x4C); }
- public int RibbonCountG3Cool { get => (int)(RIB0 >> 00) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 00)) | (uint)(value & 7) << 00); }
- public int RibbonCountG3Beauty { get => (int)(RIB0 >> 03) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 03)) | (uint)(value & 7) << 03); }
- public int RibbonCountG3Cute { get => (int)(RIB0 >> 06) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 06)) | (uint)(value & 7) << 06); }
- public int RibbonCountG3Smart { get => (int)(RIB0 >> 09) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 09)) | (uint)(value & 7) << 09); }
- public int RibbonCountG3Tough { get => (int)(RIB0 >> 12) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 12)) | (uint)(value & 7) << 12); }
- public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (uint)(RIB0 & ~(1 << 15) | (uint)(value ? 1 << 15 : 0)); }
- public bool RibbonWinning { get => (RIB0 & (1 << 16)) == 1 << 16; set => RIB0 = (uint)(RIB0 & ~(1 << 16) | (uint)(value ? 1 << 16 : 0)); }
- public bool RibbonVictory { get => (RIB0 & (1 << 17)) == 1 << 17; set => RIB0 = (uint)(RIB0 & ~(1 << 17) | (uint)(value ? 1 << 17 : 0)); }
- public bool RibbonArtist { get => (RIB0 & (1 << 18)) == 1 << 18; set => RIB0 = (uint)(RIB0 & ~(1 << 18) | (uint)(value ? 1 << 18 : 0)); }
- public bool RibbonEffort { get => (RIB0 & (1 << 19)) == 1 << 19; set => RIB0 = (uint)(RIB0 & ~(1 << 19) | (uint)(value ? 1 << 19 : 0)); }
- public bool RibbonChampionBattle { get => (RIB0 & (1 << 20)) == 1 << 20; set => RIB0 = (uint)(RIB0 & ~(1 << 20) | (uint)(value ? 1 << 20 : 0)); }
- public bool RibbonChampionRegional { get => (RIB0 & (1 << 21)) == 1 << 21; set => RIB0 = (uint)(RIB0 & ~(1 << 21) | (uint)(value ? 1 << 21 : 0)); }
- public bool RibbonChampionNational { get => (RIB0 & (1 << 22)) == 1 << 22; set => RIB0 = (uint)(RIB0 & ~(1 << 22) | (uint)(value ? 1 << 22 : 0)); }
- public bool RibbonCountry { get => (RIB0 & (1 << 23)) == 1 << 23; set => RIB0 = (uint)(RIB0 & ~(1 << 23) | (uint)(value ? 1 << 23 : 0)); }
- public bool RibbonNational { get => (RIB0 & (1 << 24)) == 1 << 24; set => RIB0 = (uint)(RIB0 & ~(1 << 24) | (uint)(value ? 1 << 24 : 0)); }
- public bool RibbonEarth { get => (RIB0 & (1 << 25)) == 1 << 25; set => RIB0 = (uint)(RIB0 & ~(1 << 25) | (uint)(value ? 1 << 25 : 0)); }
- public bool RibbonWorld { get => (RIB0 & (1 << 26)) == 1 << 26; set => RIB0 = (uint)(RIB0 & ~(1 << 26) | (uint)(value ? 1 << 26 : 0)); }
- public bool Unused1 { get => (RIB0 & (1 << 27)) == 1 << 27; set => RIB0 = (uint)(RIB0 & ~(1 << 27) | (uint)(value ? 1 << 27 : 0)); }
- public bool Unused2 { get => (RIB0 & (1 << 28)) == 1 << 28; set => RIB0 = (uint)(RIB0 & ~(1 << 28) | (uint)(value ? 1 << 28 : 0)); }
- public bool Unused3 { get => (RIB0 & (1 << 29)) == 1 << 29; set => RIB0 = (uint)(RIB0 & ~(1 << 29) | (uint)(value ? 1 << 29 : 0)); }
- public bool Unused4 { get => (RIB0 & (1 << 30)) == 1 << 30; set => RIB0 = (uint)(RIB0 & ~(1 << 30) | (uint)(value ? 1 << 30 : 0)); }
+ public override int RibbonCountG3Cool { get => (int)(RIB0 >> 00) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 00)) | (uint)(value & 7) << 00); }
+ public override int RibbonCountG3Beauty { get => (int)(RIB0 >> 03) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 03)) | (uint)(value & 7) << 03); }
+ public override int RibbonCountG3Cute { get => (int)(RIB0 >> 06) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 06)) | (uint)(value & 7) << 06); }
+ public override int RibbonCountG3Smart { get => (int)(RIB0 >> 09) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 09)) | (uint)(value & 7) << 09); }
+ public override int RibbonCountG3Tough { get => (int)(RIB0 >> 12) & 7; set => RIB0 = (uint)((RIB0 & ~(7 << 12)) | (uint)(value & 7) << 12); }
+ public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (uint)(RIB0 & ~(1 << 15) | (uint)(value ? 1 << 15 : 0)); }
+ public override bool RibbonWinning { get => (RIB0 & (1 << 16)) == 1 << 16; set => RIB0 = (uint)(RIB0 & ~(1 << 16) | (uint)(value ? 1 << 16 : 0)); }
+ public override bool RibbonVictory { get => (RIB0 & (1 << 17)) == 1 << 17; set => RIB0 = (uint)(RIB0 & ~(1 << 17) | (uint)(value ? 1 << 17 : 0)); }
+ public override bool RibbonArtist { get => (RIB0 & (1 << 18)) == 1 << 18; set => RIB0 = (uint)(RIB0 & ~(1 << 18) | (uint)(value ? 1 << 18 : 0)); }
+ public override bool RibbonEffort { get => (RIB0 & (1 << 19)) == 1 << 19; set => RIB0 = (uint)(RIB0 & ~(1 << 19) | (uint)(value ? 1 << 19 : 0)); }
+ public override bool RibbonChampionBattle { get => (RIB0 & (1 << 20)) == 1 << 20; set => RIB0 = (uint)(RIB0 & ~(1 << 20) | (uint)(value ? 1 << 20 : 0)); }
+ public override bool RibbonChampionRegional { get => (RIB0 & (1 << 21)) == 1 << 21; set => RIB0 = (uint)(RIB0 & ~(1 << 21) | (uint)(value ? 1 << 21 : 0)); }
+ public override bool RibbonChampionNational { get => (RIB0 & (1 << 22)) == 1 << 22; set => RIB0 = (uint)(RIB0 & ~(1 << 22) | (uint)(value ? 1 << 22 : 0)); }
+ public override bool RibbonCountry { get => (RIB0 & (1 << 23)) == 1 << 23; set => RIB0 = (uint)(RIB0 & ~(1 << 23) | (uint)(value ? 1 << 23 : 0)); }
+ public override bool RibbonNational { get => (RIB0 & (1 << 24)) == 1 << 24; set => RIB0 = (uint)(RIB0 & ~(1 << 24) | (uint)(value ? 1 << 24 : 0)); }
+ public override bool RibbonEarth { get => (RIB0 & (1 << 25)) == 1 << 25; set => RIB0 = (uint)(RIB0 & ~(1 << 25) | (uint)(value ? 1 << 25 : 0)); }
+ public override bool RibbonWorld { get => (RIB0 & (1 << 26)) == 1 << 26; set => RIB0 = (uint)(RIB0 & ~(1 << 26) | (uint)(value ? 1 << 26 : 0)); }
+ public override bool Unused1 { get => (RIB0 & (1 << 27)) == 1 << 27; set => RIB0 = (uint)(RIB0 & ~(1 << 27) | (uint)(value ? 1 << 27 : 0)); }
+ public override bool Unused2 { get => (RIB0 & (1 << 28)) == 1 << 28; set => RIB0 = (uint)(RIB0 & ~(1 << 28) | (uint)(value ? 1 << 28 : 0)); }
+ public override bool Unused3 { get => (RIB0 & (1 << 29)) == 1 << 29; set => RIB0 = (uint)(RIB0 & ~(1 << 29) | (uint)(value ? 1 << 29 : 0)); }
+ public override bool Unused4 { get => (RIB0 & (1 << 30)) == 1 << 30; set => RIB0 = (uint)(RIB0 & ~(1 << 30) | (uint)(value ? 1 << 30 : 0)); }
public override bool FatefulEncounter { get => RIB0 >> 31 == 1; set => RIB0 = (RIB0 & ~(1 << 31)) | (uint)(value ? 1 << 31 : 0); }
#endregion
public override int Stat_Level { get => Data[0x54]; set => Data[0x54] = (byte)value; }
+ public sbyte HeldMailID { get => (sbyte)Data[0x55]; set => Data[0x55] = (byte)value; }
public override int Stat_HPCurrent { get => BitConverter.ToUInt16(Data, 0x56); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x56); }
public override int Stat_HPMax { get => BitConverter.ToUInt16(Data, 0x58); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x58); }
public override int Stat_ATK { get => BitConverter.ToUInt16(Data, 0x5A); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5A); }
@@ -151,29 +144,10 @@ public PK3(byte[] decryptedData = null, string ident = null)
public override int Stat_SPE { get => BitConverter.ToUInt16(Data, 0x5E); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x5E); }
public override int Stat_SPA { get => BitConverter.ToUInt16(Data, 0x60); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x60); }
public override int Stat_SPD { get => BitConverter.ToUInt16(Data, 0x62); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x62); }
- public sbyte HeldMailID { get => (sbyte)Data[0x55]; set => Data[0x55] = (byte)value; }
// Generated Attributes
public override int AbilityNumber { get => 1 << (AbilityBit ? 1 : 0); set => AbilityBit = value > 1; } // 1/2 -> 0/1
- public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3);
- public override int TSV => (TID ^ SID) >> 3;
public override bool Japanese => IsEgg || Language == (int)LanguageID.Japanese;
- public override bool WasEvent => Met_Location == 255; // Fateful
- public override bool WasIngameTrade => Met_Location == 254; // Trade
- public override bool WasGiftEgg => IsEgg && Met_Location == 253; // Gift Egg, indistinguible from normal eggs after hatch
- public override bool WasEventEgg => IsEgg && Met_Location == 255; // Event Egg, indistinguible from normal eggs after hatch
-
- // Maximums
- public override int MaxMoveID => Legal.MaxMoveID_3;
- public override int MaxSpeciesID => Legal.MaxSpeciesID_3;
- public override int MaxAbilityID => Legal.MaxAbilityID_3;
- public override int MaxItemID => Legal.MaxItemID_3;
- public override int MaxBallID => Legal.MaxBallID_3;
- public override int MaxGameID => Legal.MaxGameID_3;
- public override int MaxIV => 31;
- public override int MaxEV => 255;
- public override int OTLength => 7;
- public override int NickLength => 10;
protected override byte[] Encrypt()
{
@@ -305,5 +279,20 @@ public PK4 ConvertToPK4()
pk4.RefreshChecksum();
return pk4;
}
+
+ public XK3 ConvertToXK3()
+ {
+ var pk = ConvertTo();
+ pk.SetStats(GetStats(PersonalTable.RS[pk.Species]));
+ pk.Stat_Level = pk.CurrentLevel;
+ return pk;
+ }
+ public CK3 ConvertToCK3()
+ {
+ var pk = ConvertTo();
+ pk.SetStats(GetStats(PersonalTable.RS[pk.Species]));
+ pk.Stat_Level = pk.CurrentLevel;
+ return pk;
+ }
}
}
diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs
index 02155c017..e48d79f18 100644
--- a/PKHeX.Core/PKM/PKM.cs
+++ b/PKHeX.Core/PKM/PKM.cs
@@ -901,59 +901,6 @@ public int GetFlawlessIVCount()
return 0;
}
- ///
- /// Converts a or to .
- ///
- /// format
- public PKM ConvertToCK3()
- {
- if (Format != 3)
- return null;
- if (GetType() == typeof(CK3))
- return this;
- var pk = new CK3();
- TransferPropertiesWithReflection(this is XK3 ? ConvertToPK3() : this, pk);
- pk.SetStats(GetStats(PersonalTable.RS[pk.Species]));
- pk.Stat_Level = pk.CurrentLevel;
- return pk;
- }
- ///
- /// Converts a or to .
- ///
- /// format
- public PKM ConvertToXK3()
- {
- if (Format != 3)
- return null;
- if (GetType() == typeof(XK3))
- return this;
- var pk = new XK3();
- TransferPropertiesWithReflection(this is CK3 ? ConvertToPK3() : this, pk);
- pk.SetStats(GetStats(PersonalTable.RS[pk.Species]));
- pk.Stat_Level = pk.CurrentLevel;
- return pk;
- }
- ///
- /// Converts a or to .
- ///
- /// format
- public PKM ConvertToPK3()
- {
- if (Format != 3)
- return null;
- if (GetType() == typeof(PK3))
- return this;
- var pk = new PK3();
- TransferPropertiesWithReflection(this, pk);
-
- // Transferring XK3 to PK3 when it originates from XD sets the fateful encounter (obedience) flag.
- if (this is XK3 xk3 && xk3.Version == 15 && xk3.IsOriginXD())
- pk.FatefulEncounter = true;
-
- pk.RefreshChecksum();
- return pk;
- }
-
///
/// Applies all shared properties from to .
///
@@ -964,7 +911,7 @@ public void TransferPropertiesWithReflection(PKM Source, PKM Destination)
// 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).Reverse())
+ foreach (string property in SourceProperties.Intersect(DestinationProperties))
{
var prop = ReflectUtil.GetValue(this, property);
if (prop != null && !(prop is byte[]))
diff --git a/PKHeX.Core/PKM/PKMConverter.cs b/PKHeX.Core/PKM/PKMConverter.cs
index 88f385050..c94d6c774 100644
--- a/PKHeX.Core/PKM/PKMConverter.cs
+++ b/PKHeX.Core/PKM/PKMConverter.cs
@@ -280,19 +280,20 @@ private static PKM ConvertPKM(PKM pk, Type PKMType, Type fromType, int toFormat,
}
break;
case nameof(CK3):
+ pkm = ((CK3)pkm).ConvertToPK3();
+ goto case nameof(PK3); // fall through
case nameof(XK3):
- // interconverting C/XD needs to visit main series format
- // ends up stripping purification/shadow etc stats
- pkm = pkm.ConvertToPK3();
+ pkm = ((XK3)pkm).ConvertToPK3();
goto case nameof(PK3); // fall through
case nameof(PK3):
- if (toFormat == 3) // Gen3 Inter-trading
+ if (toFormat == 3)
{
- pkm = InterConvertPK3(pkm, PKMType);
+ if (PKMType == typeof(CK3))
+ pkm = ((PK3)pkm).ConvertToCK3();
+ else if (PKMType == typeof(XK3))
+ pkm = ((PK3)pkm).ConvertToXK3();
break;
}
- if (fromType.Name != nameof(PK3))
- pkm = pkm.ConvertToPK3();
pkm = ((PK3) pkm).ConvertToPK4();
if (toFormat == 4)
@@ -356,28 +357,6 @@ private static bool IsNotTransferrable(PKM pk, out string comment)
}
}
- ///
- /// Converts a PKM from one Generation 3 format to another. If it matches the destination format, the conversion will automatically return.
- ///
- /// PKM to convert
- /// Format/Type to convert to
- /// , , and are supported.
- /// Converted PKM
- private static PKM InterConvertPK3(PKM pk, Type desiredFormatType)
- {
- // if already converted it instantly returns
- switch (desiredFormatType.Name)
- {
- case nameof(CK3):
- return pk.ConvertToCK3();
- case nameof(XK3):
- return pk.ConvertToXK3();
- case nameof(PK3):
- return pk.ConvertToPK3();
- default: throw new FormatException();
- }
- }
-
///
/// Force hatches a PKM by applying the current species name and a valid Met Location from the origin game.
///
diff --git a/PKHeX.Core/PKM/Shared/_K3.cs b/PKHeX.Core/PKM/Shared/_K3.cs
new file mode 100644
index 000000000..599be1d37
--- /dev/null
+++ b/PKHeX.Core/PKM/Shared/_K3.cs
@@ -0,0 +1,152 @@
+namespace PKHeX.Core
+{
+ ///
+ /// Generation 3 Base Class
+ ///
+ public abstract class _K3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3
+ {
+ // Maximums
+ public override int MaxMoveID => Legal.MaxMoveID_3;
+ public override int MaxSpeciesID => Legal.MaxSpeciesID_3;
+ public override int MaxAbilityID => Legal.MaxAbilityID_3;
+ public override int MaxItemID => Legal.MaxItemID_3;
+ public override int MaxBallID => Legal.MaxBallID_3;
+ public override int MaxGameID => Legal.MaxGameID_3;
+ public override int MaxIV => 31;
+ public override int MaxEV => 255;
+ public override int OTLength => 7;
+ public override int NickLength => 10;
+
+ // Generated Attributes
+ public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3);
+ public override int TSV => (TID ^ SID) >> 3;
+ public override bool Japanese => Language == (int)LanguageID.Japanese;
+ public override bool WasEvent => Met_Location == 255; // Fateful
+ public override bool WasIngameTrade => Met_Location == 254; // Trade
+ public override bool WasGiftEgg => IsEgg && Met_Location == 253; // Gift Egg, indistinguible from normal eggs after hatch
+ public override bool WasEventEgg => IsEgg && Met_Location == 255; // Event Egg, indistinguible from normal eggs after hatch
+
+ public override int Ability { get { int[] abils = PersonalInfo.Abilities; return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } }
+ public override uint EncryptionConstant { get => PID; set { } }
+ public override int Nature { get => (int)(PID % 25); set { } }
+ public override int AltForm { get => Species == 201 ? PKX.GetUnownForm(PID) : 0; set { } }
+ public override bool IsNicknamed { get => PKX.IsNicknamedAnyLanguage(Species, Nickname, Format); set { } }
+ public override int Gender { get => PKX.GetGenderFromPID(Species, PID); set { } }
+ public override int Characteristic => -1;
+ public override int CurrentFriendship { get => OT_Friendship; set => OT_Friendship = value; }
+ public override int CurrentHandler { get => 0; set { } }
+ public override int Egg_Location { get => 0; set { } }
+
+ public abstract bool RibbonEarth { get; set; }
+ public abstract bool RibbonNational { get; set; }
+ public abstract bool RibbonCountry { get; set; }
+ public abstract bool RibbonChampionBattle { get; set; }
+ public abstract bool RibbonChampionRegional { get; set; }
+ public abstract bool RibbonChampionNational { get; set; }
+ public abstract bool RibbonChampionG3Hoenn { get; set; }
+ public abstract bool RibbonArtist { get; set; }
+ public abstract bool RibbonEffort { get; set; }
+ public abstract bool RibbonWinning { get; set; }
+ public abstract bool RibbonVictory { get; set; }
+ public abstract int RibbonCountG3Cool { get; set; }
+ public abstract int RibbonCountG3Beauty { get; set; }
+ public abstract int RibbonCountG3Cute { get; set; }
+ public abstract int RibbonCountG3Smart { get; set; }
+ public abstract int RibbonCountG3Tough { get; set; }
+ public abstract bool RibbonWorld { get; set; }
+ public abstract bool Unused1 { get; set; }
+ public abstract bool Unused2 { get; set; }
+ public abstract bool Unused3 { get; set; }
+ public abstract bool Unused4 { get; set; }
+
+ ///
+ /// Interconversion for Generation 3 formats.
+ ///
+ /// Generation 3 format to convert to
+ /// New object with transferred properties.
+ protected T ConvertTo() where T : _K3, new()
+ {
+ return new T // Convert away!
+ {
+ Species = Species,
+ Language = Language,
+ PID = PID,
+ TID = TID,
+ SID = SID,
+ EXP = EXP,
+ HeldItem = HeldItem,
+ AbilityNumber = AbilityNumber,
+ IsEgg = IsEgg,
+ FatefulEncounter = FatefulEncounter,
+
+ Met_Location = Met_Location,
+ Met_Level = Met_Level,
+ Version = Version,
+ Ball = Ball,
+
+ Nickname = Nickname,
+ OT_Name = OT_Name,
+ OT_Gender = OT_Gender,
+ OT_Friendship = OT_Friendship,
+
+ Move1_PPUps = Move1_PPUps,
+ Move2_PPUps = Move2_PPUps,
+ Move3_PPUps = Move3_PPUps,
+ Move4_PPUps = Move4_PPUps,
+ Move1 = Move1,
+ Move2 = Move2,
+ Move3 = Move3,
+ Move4 = Move4,
+ Move1_PP = Move1_PP,
+ Move2_PP = Move2_PP,
+ Move3_PP = Move3_PP,
+ Move4_PP = Move4_PP,
+
+ IV_HP = IV_HP,
+ IV_ATK = IV_ATK,
+ IV_DEF = IV_DEF,
+ IV_SPE = IV_SPE,
+ IV_SPA = IV_SPA,
+ IV_SPD = IV_SPD,
+ EV_HP = EV_HP,
+ EV_ATK = EV_ATK,
+ EV_DEF = EV_DEF,
+ EV_SPE = EV_SPE,
+ EV_SPA = EV_SPA,
+ EV_SPD = EV_SPD,
+ CNT_Cool = CNT_Cool,
+ CNT_Beauty = CNT_Beauty,
+ CNT_Cute = CNT_Cute,
+ CNT_Smart = CNT_Smart,
+ CNT_Tough = CNT_Tough,
+ CNT_Sheen = CNT_Sheen,
+
+ PKRS_Days = PKRS_Days,
+ PKRS_Strain = PKRS_Strain,
+
+ // Transfer Ribbons
+ RibbonCountG3Cool = RibbonCountG3Cool,
+ RibbonCountG3Beauty = RibbonCountG3Beauty,
+ RibbonCountG3Cute = RibbonCountG3Cute,
+ RibbonCountG3Smart = RibbonCountG3Smart,
+ RibbonCountG3Tough = RibbonCountG3Tough,
+ RibbonChampionG3Hoenn = RibbonChampionG3Hoenn,
+ RibbonWinning = RibbonWinning,
+ RibbonVictory = RibbonVictory,
+ RibbonArtist = RibbonArtist,
+ RibbonEffort = RibbonEffort,
+ RibbonChampionBattle = RibbonChampionBattle,
+ RibbonChampionRegional = RibbonChampionRegional,
+ RibbonChampionNational = RibbonChampionNational,
+ RibbonCountry = RibbonCountry,
+ RibbonNational = RibbonNational,
+ RibbonEarth = RibbonEarth,
+ RibbonWorld = RibbonWorld,
+ Unused1 = Unused1,
+ Unused2 = Unused2,
+ Unused3 = Unused3,
+ Unused4 = Unused4,
+ };
+ }
+ }
+}
diff --git a/PKHeX.Core/PKM/XK3.cs b/PKHeX.Core/PKM/XK3.cs
index 7658c1a48..db73bfbaa 100644
--- a/PKHeX.Core/PKM/XK3.cs
+++ b/PKHeX.Core/PKM/XK3.cs
@@ -3,7 +3,7 @@
namespace PKHeX.Core
{
/// Generation 3 format, exclusively for Pokémon XD.
- public sealed class XK3 : PKM, IRibbonSetEvent3, IRibbonSetCommon3, IRibbonSetUnique3, IRibbonSetOnly3, IShadowPKM
+ public sealed class XK3 : _K3, IShadowPKM
{
public static readonly byte[] ExtraBytes =
{
@@ -24,6 +24,7 @@ public XK3(byte[] decryptedData = null, string ident = null)
if (Data.Length != SIZE_PARTY)
Array.Resize(ref Data, SIZE_PARTY);
}
+ public XK3() => Data = new byte[SIZE_PARTY];
public override PKM Clone() => new XK3((byte[])Data.Clone(), Identifier) {Purification = Purification};
private string GetString(int Offset, int Count) => StringConverter.GetBEString3(Data, Offset, Count);
@@ -33,19 +34,6 @@ public XK3(byte[] decryptedData = null, string ident = null)
public override byte[] Nickname_Trash { get => GetData(0x4E, 20); set { if (value?.Length == 20) value.CopyTo(Data, 0x4E); } }
public override byte[] OT_Trash { get => GetData(0x38, 20); set { if (value?.Length == 20) value.CopyTo(Data, 0x38); } }
- // Future Attributes
- public override uint EncryptionConstant { get => PID; set { } }
- public override int Nature { get => (int)(PID % 25); set { } }
- public override int AltForm { get => Species == 201 ? PKX.GetUnownForm(PID) : 0; set { } }
-
- public override bool IsNicknamed { get => PKX.IsNicknamedAnyLanguage(Species, Nickname, Format); set { } }
- public override int Gender { get => PKX.GetGenderFromPID(Species, PID); set { } }
- public override int Characteristic => -1;
- public override int CurrentFriendship { get => OT_Friendship; set => OT_Friendship = value; }
- public override int Ability { get { int[] abils = PersonalTable.RS.GetAbilities(Species, 0); return abils[abils[1] == 0 ? 0 : AbilityNumber >> 1]; } set { } }
- public override int CurrentHandler { get => 0; set { } }
- public override int Egg_Location { get => 0; set { } }
-
// Silly Attributes
public override ushort Sanity { get => 0; set { } } // valid flag set in pkm structure.
public override ushort Checksum { get => SaveUtil.CRC16_CCITT(Data); set { } } // totally false, just a way to get a 'random' ident for the pkm.
@@ -96,22 +84,22 @@ public XK3(byte[] decryptedData = null, string ident = null)
private string Nickname2 { get => GetString(0x64, 20); set => SetString(value, 10).CopyTo(Data, 0x64); } // +2 terminator
// 0x7A-0x7B Unknown
private ushort RIB0 { get => BigEndian.ToUInt16(Data, 0x7C); set => BigEndian.GetBytes(value).CopyTo(Data, 0x7C); }
- public bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (ushort)(RIB0 & ~(1 << 15) | (ushort)(value ? 1 << 15 : 0)); }
- public bool RibbonWinning { get => (RIB0 & (1 << 14)) == 1 << 14; set => RIB0 = (ushort)(RIB0 & ~(1 << 14) | (ushort)(value ? 1 << 14 : 0)); }
- public bool RibbonVictory { get => (RIB0 & (1 << 13)) == 1 << 13; set => RIB0 = (ushort)(RIB0 & ~(1 << 13) | (ushort)(value ? 1 << 13 : 0)); }
- public bool RibbonArtist { get => (RIB0 & (1 << 12)) == 1 << 12; set => RIB0 = (ushort)(RIB0 & ~(1 << 12) | (ushort)(value ? 1 << 12 : 0)); }
- public bool RibbonEffort { get => (RIB0 & (1 << 11)) == 1 << 11; set => RIB0 = (ushort)(RIB0 & ~(1 << 11) | (ushort)(value ? 1 << 11 : 0)); }
- public bool RibbonChampionBattle { get => (RIB0 & (1 << 10)) == 1 << 10; set => RIB0 = (ushort)(RIB0 & ~(1 << 10) | (ushort)(value ? 1 << 10 : 0)); }
- public bool RibbonChampionRegional { get => (RIB0 & (1 << 09)) == 1 << 09; set => RIB0 = (ushort)(RIB0 & ~(1 << 09) | (ushort)(value ? 1 << 09 : 0)); }
- public bool RibbonChampionNational { get => (RIB0 & (1 << 08)) == 1 << 08; set => RIB0 = (ushort)(RIB0 & ~(1 << 08) | (ushort)(value ? 1 << 08 : 0)); }
- public bool RibbonCountry { get => (RIB0 & (1 << 07)) == 1 << 07; set => RIB0 = (ushort)(RIB0 & ~(1 << 07) | (ushort)(value ? 1 << 07 : 0)); }
- public bool RibbonNational { get => (RIB0 & (1 << 06)) == 1 << 06; set => RIB0 = (ushort)(RIB0 & ~(1 << 06) | (ushort)(value ? 1 << 06 : 0)); }
- public bool RibbonEarth { get => (RIB0 & (1 << 05)) == 1 << 05; set => RIB0 = (ushort)(RIB0 & ~(1 << 05) | (ushort)(value ? 1 << 05 : 0)); }
- public bool RibbonWorld { get => (RIB0 & (1 << 04)) == 1 << 04; set => RIB0 = (ushort)(RIB0 & ~(1 << 04) | (ushort)(value ? 1 << 04 : 0)); }
- public bool Unused1 { get => (RIB0 & (1 << 03)) == 1 << 03; set => RIB0 = (ushort)(RIB0 & ~(1 << 03) | (ushort)(value ? 1 << 03 : 0)); }
- public bool Unused2 { get => (RIB0 & (1 << 02)) == 1 << 02; set => RIB0 = (ushort)(RIB0 & ~(1 << 02) | (ushort)(value ? 1 << 02 : 0)); }
- public bool Unused3 { get => (RIB0 & (1 << 01)) == 1 << 01; set => RIB0 = (ushort)(RIB0 & ~(1 << 01) | (ushort)(value ? 1 << 01 : 0)); }
- public bool Unused4 { get => (RIB0 & (1 << 00)) == 1 << 00; set => RIB0 = (ushort)(RIB0 & ~(1 << 00) | (ushort)(value ? 1 << 00 : 0)); }
+ public override bool RibbonChampionG3Hoenn { get => (RIB0 & (1 << 15)) == 1 << 15; set => RIB0 = (ushort)(RIB0 & ~(1 << 15) | (ushort)(value ? 1 << 15 : 0)); }
+ public override bool RibbonWinning { get => (RIB0 & (1 << 14)) == 1 << 14; set => RIB0 = (ushort)(RIB0 & ~(1 << 14) | (ushort)(value ? 1 << 14 : 0)); }
+ public override bool RibbonVictory { get => (RIB0 & (1 << 13)) == 1 << 13; set => RIB0 = (ushort)(RIB0 & ~(1 << 13) | (ushort)(value ? 1 << 13 : 0)); }
+ public override bool RibbonArtist { get => (RIB0 & (1 << 12)) == 1 << 12; set => RIB0 = (ushort)(RIB0 & ~(1 << 12) | (ushort)(value ? 1 << 12 : 0)); }
+ public override bool RibbonEffort { get => (RIB0 & (1 << 11)) == 1 << 11; set => RIB0 = (ushort)(RIB0 & ~(1 << 11) | (ushort)(value ? 1 << 11 : 0)); }
+ public override bool RibbonChampionBattle { get => (RIB0 & (1 << 10)) == 1 << 10; set => RIB0 = (ushort)(RIB0 & ~(1 << 10) | (ushort)(value ? 1 << 10 : 0)); }
+ public override bool RibbonChampionRegional { get => (RIB0 & (1 << 09)) == 1 << 09; set => RIB0 = (ushort)(RIB0 & ~(1 << 09) | (ushort)(value ? 1 << 09 : 0)); }
+ public override bool RibbonChampionNational { get => (RIB0 & (1 << 08)) == 1 << 08; set => RIB0 = (ushort)(RIB0 & ~(1 << 08) | (ushort)(value ? 1 << 08 : 0)); }
+ public override bool RibbonCountry { get => (RIB0 & (1 << 07)) == 1 << 07; set => RIB0 = (ushort)(RIB0 & ~(1 << 07) | (ushort)(value ? 1 << 07 : 0)); }
+ public override bool RibbonNational { get => (RIB0 & (1 << 06)) == 1 << 06; set => RIB0 = (ushort)(RIB0 & ~(1 << 06) | (ushort)(value ? 1 << 06 : 0)); }
+ public override bool RibbonEarth { get => (RIB0 & (1 << 05)) == 1 << 05; set => RIB0 = (ushort)(RIB0 & ~(1 << 05) | (ushort)(value ? 1 << 05 : 0)); }
+ public override bool RibbonWorld { get => (RIB0 & (1 << 04)) == 1 << 04; set => RIB0 = (ushort)(RIB0 & ~(1 << 04) | (ushort)(value ? 1 << 04 : 0)); }
+ public override bool Unused1 { get => (RIB0 & (1 << 03)) == 1 << 03; set => RIB0 = (ushort)(RIB0 & ~(1 << 03) | (ushort)(value ? 1 << 03 : 0)); }
+ public override bool Unused2 { get => (RIB0 & (1 << 02)) == 1 << 02; set => RIB0 = (ushort)(RIB0 & ~(1 << 02) | (ushort)(value ? 1 << 02 : 0)); }
+ public override bool Unused3 { get => (RIB0 & (1 << 01)) == 1 << 01; set => RIB0 = (ushort)(RIB0 & ~(1 << 01) | (ushort)(value ? 1 << 01 : 0)); }
+ public override bool Unused4 { get => (RIB0 & (1 << 00)) == 1 << 00; set => RIB0 = (ushort)(RIB0 & ~(1 << 00) | (ushort)(value ? 1 << 00 : 0)); }
// 0x7E-0x7F Unknown
// Moves
@@ -182,45 +170,44 @@ public override int EV_SPE
public override int CNT_Cute { get => Data[0xB0]; set => Data[0xB0] = (byte)value; }
public override int CNT_Smart { get => Data[0xB1]; set => Data[0xB1] = (byte)value; }
public override int CNT_Tough { get => Data[0xB2]; set => Data[0xB2] = (byte)value; }
- public int RibbonCountG3Cool { get => Data[0xB3]; set => Data[0xB3] = (byte)value; }
- public int RibbonCountG3Beauty { get => Data[0xB4]; set => Data[0xB4] = (byte)value; }
- public int RibbonCountG3Cute { get => Data[0xB5]; set => Data[0xB5] = (byte)value; }
- public int RibbonCountG3Smart { get => Data[0xB6]; set => Data[0xB6] = (byte)value; }
- public int RibbonCountG3Tough { get => Data[0xB7]; set => Data[0xB7] = (byte)value; }
+ public override int RibbonCountG3Cool { get => Data[0xB3]; set => Data[0xB3] = (byte)value; }
+ public override int RibbonCountG3Beauty { get => Data[0xB4]; set => Data[0xB4] = (byte)value; }
+ public override int RibbonCountG3Cute { get => Data[0xB5]; set => Data[0xB5] = (byte)value; }
+ public override int RibbonCountG3Smart { get => Data[0xB6]; set => Data[0xB6] = (byte)value; }
+ public override int RibbonCountG3Tough { get => Data[0xB7]; set => Data[0xB7] = (byte)value; }
public int ShadowID { get => BigEndian.ToUInt16(Data, 0xBA); set => BigEndian.GetBytes((ushort)value).CopyTo(Data, 0xBA); }
// Purification information is stored in the save file and accessed based on the Shadow ID.
public int Purification { get; set; }
- // Generated Attributes
- public override int PSV => (int)((PID >> 16 ^ PID & 0xFFFF) >> 3);
- public override int TSV => (TID ^ SID) >> 3;
- public override bool Japanese => Language == (int)LanguageID.Japanese;
-
protected override byte[] Encrypt()
{
return (byte[])Data.Clone();
}
- // Maximums
- public override int MaxMoveID => Legal.MaxMoveID_3;
- public override int MaxSpeciesID => Legal.MaxSpeciesID_3;
- public override int MaxAbilityID => Legal.MaxAbilityID_3;
- public override int MaxItemID => Legal.MaxItemID_3;
- public override int MaxBallID => Legal.MaxBallID_3;
- public override int MaxGameID => Legal.MaxGameID_3;
- public override int MaxIV => 31;
- public override int MaxEV => 252;
- public override int OTLength => 7;
- public override int NickLength => 10;
- public bool IsOriginXD()
+ public PK3 ConvertToPK3()
+ {
+ var pk = ConvertTo();
+ if (Version == 15)
+ {
+ // Transferring XK3 to PK3 when it originates from XD sets the fateful encounter (obedience) flag.
+ if (ShadowID != 0)
+ pk.RibbonEarth = true; // must be purified before trading away; force purify
+ if (IsOriginXD())
+ pk.FatefulEncounter = true;
+ }
+ pk.RefreshChecksum();
+ return pk;
+ }
+
+ private bool IsOriginXD()
{
if (ShadowID != 0)
return true;
return IsOriginXD(Species, Met_Level);
}
- public static bool IsOriginXD(int species, int metLevel)
+ private static bool IsOriginXD(int species, int metLevel)
{
switch (species)
{
diff --git a/PKHeX.Core/Ribbons/IRibbonSetOnly3.cs b/PKHeX.Core/Ribbons/IRibbonSetOnly3.cs
index a385b4bda..a312195f3 100644
--- a/PKHeX.Core/Ribbons/IRibbonSetOnly3.cs
+++ b/PKHeX.Core/Ribbons/IRibbonSetOnly3.cs
@@ -8,6 +8,12 @@ internal interface IRibbonSetOnly3
int RibbonCountG3Cute { get; set; }
int RibbonCountG3Smart { get; set; }
int RibbonCountG3Tough { get; set; }
+
+ bool RibbonWorld { get; set; }
+ bool Unused1 { get; set; }
+ bool Unused2 { get; set; }
+ bool Unused3 { get; set; }
+ bool Unused4 { get; set; }
}
internal static partial class RibbonExtensions
@@ -16,6 +22,10 @@ internal static partial class RibbonExtensions
{
nameof(IRibbonSetOnly3.RibbonCountG3Cool), nameof(IRibbonSetOnly3.RibbonCountG3Beauty), nameof(IRibbonSetOnly3.RibbonCountG3Cute),
nameof(IRibbonSetOnly3.RibbonCountG3Smart), nameof(IRibbonSetOnly3.RibbonCountG3Tough),
+
+ nameof(IRibbonSetOnly3.RibbonWorld),
+ nameof(IRibbonSetOnly3.Unused1), nameof(IRibbonSetOnly3.Unused2),
+ nameof(IRibbonSetOnly3.Unused3), nameof(IRibbonSetOnly3.Unused4),
};
internal static int[] RibbonCounts(this IRibbonSetOnly3 set)
{