From 3ded8b61c6b86fb002a30e8783525172e33c3e17 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 27 Aug 2016 01:52:34 -0700 Subject: [PATCH 01/16] Initial PK1 implementation. --- PKHeX/PKHeX.csproj | 2 + PKHeX/PKM/PK1.cs | 307 +++++++++++++++++++++++++++++++++++++++++ PKHeX/PKM/PKX.cs | 21 +++ PKHeX/Util/ByteUtil.cs | 49 +++++++ 4 files changed, 379 insertions(+) create mode 100644 PKHeX/PKM/PK1.cs create mode 100644 PKHeX/Util/ByteUtil.cs diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index eae839e4b..4af47f6a3 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -95,6 +95,7 @@ + @@ -300,6 +301,7 @@ SplashScreen.cs + diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs new file mode 100644 index 000000000..89370505f --- /dev/null +++ b/PKHeX/PKM/PK1.cs @@ -0,0 +1,307 @@ +using System; +using System.Linq; + +namespace PKHeX +{ + class PK1 : PKM + { + // Internal use only + protected byte[] otname; + protected byte[] nick; + + public sealed override int SIZE_PARTY => PKX.SIZE_1PARTY; + public override int SIZE_STORED => PKX.SIZE_1STORED; + internal const int STRLEN_J = 6; + internal const int STRLEN_U = 11; + private int StringLength => Japanese ? STRLEN_J : STRLEN_U; + + public override int Format => 1; + + public bool Japanese => otname.Length == STRLEN_J; + + public PK1(byte[] decryptedData = null, string ident = null, bool jp = false) + { + Data = (byte[])(decryptedData ?? new byte[SIZE_PARTY]).Clone(); + Identifier = ident; + if (Data.Length != SIZE_PARTY) + Array.Resize(ref Data, SIZE_PARTY); + int strLen = STRLEN_U; + if (jp) + { + strLen = STRLEN_J; + } + otname = Enumerable.Repeat((byte) 0x50, strLen).ToArray(); + nick = Enumerable.Repeat((byte) 0x50, strLen).ToArray(); + } + + public override PKM Clone() + { + PK1 new_pk1 = new PK1(Data); + Array.Copy(otname, 0, new_pk1.otname, 0, otname.Length); + Array.Copy(nick, 0, new_pk1.nick, 0, nick.Length); + return new_pk1; + } + public override string Nickname + { + get { return PKX.getG1Str(nick, Japanese); } + set + { + byte[] strdata = PKX.setG1Str(value, Japanese); + if (strdata.Length > StringLength) + throw new ArgumentOutOfRangeException("OT Name too long for given PK1"); + strdata.CopyTo(nick, 0); + } + } + + public override string OT_Name + { + get { return PKX.getG1Str(otname, Japanese); } + set + { + byte[] strdata = PKX.setG1Str(value, Japanese); + if (strdata.Length > StringLength) + throw new ArgumentOutOfRangeException("OT Name too long for given PK1"); + strdata.CopyTo(otname, 0); + } + } + + public override byte[] Encrypt() + { + throw new NotImplementedException(); + } + + public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } + + #region Stored Attributes + public override int Species { get { return Data[0]; } set { } } + + public override int Stat_HPCurrent { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x1); } } + public int Status_Condition { get { return Data[4]; } set { Data[4] = (byte)value; } } + public int Type_A { get { return Data[5]; } set { Data[5] = (byte)value; } } + public int Type_B { get { return Data[6]; } set { Data[6] = (byte)value; } } + public int Catch_Rate { get { return Data[7]; } set { Data[7] = (byte)value; } } + public override int Move1 { get { return Data[8]; } set { Data[8] = (byte) value; } } + public override int Move2 { get { return Data[9]; } set { Data[9] = (byte)value; } } + public override int Move3 { get { return Data[10]; } set { Data[10] = (byte)value; } } + public override int Move4 { get { return Data[11]; } set { Data[11] = (byte)value; } } + public override int TID { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0xC)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0xC); } } + public override uint EXP + { + get { return Util.SwapEndianness(BitConverter.ToUInt32(Data, 0xE)) & 0x00FFFFFF; } + set { Array.Copy(BitConverter.GetBytes(Util.SwapEndianness((value << 8) & 0xFFFFFF00)), 0, Data, 0xE, 3); } + } + public override int EV_HP { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x11)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x11); } } + public override int EV_ATK { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x13)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x13); } } + public override int EV_DEF { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x15)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x15); } } + public override int EV_SPE { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x17)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x17); } } + public int EV_SPC { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x19)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x19); } } + public override int EV_SPA { get { return EV_SPC; } set { EV_SPC = value; } } + public override int EV_SPD { get { return EV_SPC; } set { EV_SPC = value; } } + public ushort DV16 { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1B)); } set { BitConverter.GetBytes(Util.SwapEndianness(value)).CopyTo(Data, 0x1B); } } + public override int IV_HP { get { return ((IV_ATK & 1) << 3) | ((IV_DEF & 1) << 2) | ((IV_SPD & 1) << 1) | ((IV_SPC & 1) << 0); } set { } } + public override int IV_ATK { get { return (DV16 >> 12) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 12)) | (ushort)((value > 0xF ? 0xF : value) << 12)); } } + public override int IV_DEF { get { return (DV16 >> 8) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 8)) | (ushort)((value > 0xF ? 0xF : value) << 8)); } } + public override int IV_SPE { get { return (DV16 >> 4) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 4)) | (ushort)((value > 0xF ? 0xF : value) << 4)); } } + public int IV_SPC { get { return (DV16 >> 0) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 0)) | (ushort)((value > 0xF ? 0xF : value) << 0)); } } + public override int IV_SPA { get { return IV_SPC; } set { IV_SPC = value; } } + public override int IV_SPD { get { return IV_SPC; } set { IV_SPC = value; } } + public override int Move1_PP { get { return Data[0x1D] & 0x3F; } set { Data[0x1D] = (byte)((Data[0x1D] & 0xC0) | (value & 0x3F)); } } + public override int Move2_PP { get { return Data[0x1E] & 0x3F; } set { Data[0x1E] = (byte)((Data[0x1E] & 0xC0) | (value & 0x3F)); } } + public override int Move3_PP { get { return Data[0x1F] & 0x3F; } set { Data[0x1F] = (byte)((Data[0x1F] & 0xC0) | (value & 0x3F)); } } + public override int Move4_PP { get { return Data[0x20] & 0x3F; } set { Data[0x20] = (byte)((Data[0x20] & 0xC0) | (value & 0x3F)); } } + public override int Move1_PPUps { get { return (Data[0x1D] & 0xC0) >> 6; } set { Data[0x1D] = (byte)((Data[0x1D] & 0x3F) | ((value & 0x3) << 6)); } } + public override int Move2_PPUps { get { return (Data[0x1E] & 0xC0) >> 6; } set { Data[0x1E] = (byte)((Data[0x1E] & 0x3F) | ((value & 0x3) << 6)); } } + public override int Move3_PPUps { get { return (Data[0x1F] & 0xC0) >> 6; } set { Data[0x1F] = (byte)((Data[0x1F] & 0x3F) | ((value & 0x3) << 6)); } } + public override int Move4_PPUps { get { return (Data[0x20] & 0xC0) >> 6; } set { Data[0x20] = (byte)((Data[0x20] & 0x3F) | ((value & 0x3) << 6)); } } + #endregion + + #region Party Attributes + public override int Stat_Level + { + get { return Data[0x21]; } + set { Data[0x21] = (byte)value; Data[0x3] = (byte)value; } + } + public override int Stat_HPMax { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x22)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x22); } } + public override int Stat_ATK { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x24)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x24); } } + public override int Stat_DEF { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x26)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x26); } } + public override int Stat_SPE { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x28)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x28); } } + public int Stat_SPC { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x2A)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x2A); } } + // Leave SPA and SPD as alias for SPC + public override int Stat_SPA { get { return Stat_SPC; } set { Stat_SPC = value; } } + public override int Stat_SPD { get { return Stat_SPC; } set { Stat_SPC = value; } } + #endregion + + #region Future, Unused Attributes + public override bool getGenderIsValid() + { + return true; + } + public override uint EncryptionConstant { get { return 0; } set { } } + public override uint PID { get { return 0; } set { } } + public override int Met_Level { get { return 0; } set { } } + public override int Nature { get { return 0; } set { } } + public override int AltForm { get { return 0; } set { } } + public override bool IsEgg { get { return false; } set { } } + public override int Gender { get { return 0; } set { } } + public override int HeldItem { get { return 0; } set { } } + public override ushort Sanity { get { return 0; } set { } } + public override ushort Checksum { get { return 0; } set { } } + public override int Language { get { return 0; } set { } } + public override bool FatefulEncounter { get { return false; } set { } } + public override int TSV => 0; + public override int PSV => 0; + public override int Characteristic => -1; + public override byte MarkByte { get { return 0; } protected set { } } + public override int CurrentFriendship { get { return 0; } set { } } + public override int Ability { get { return 0; } set { } } + public override int CurrentHandler { get { return 0; } set { } } + public override int Met_Location { get { return 0; } set { } } + public override int Egg_Location { get { return 0; } set { } } + public override int OT_Friendship { get { return 0; } set { } } + public override int OT_Gender { get { return 0; } set { } } + public override int Ball { get { return 0; } set { } } + public override int Version { get { return 0; } set { } } + public override int SID { get { return 0; } set { } } + public override int PKRS_Strain { get { return 0; } set { } } + public override int PKRS_Days { get { return 0; } set { } } + public override int CNT_Cool { get { return 0; } set { } } + public override int CNT_Beauty { get { return 0; } set { } } + public override int CNT_Cute { get { return 0; } set { } } + public override int CNT_Smart { get { return 0; } set { } } + public override int CNT_Tough { get { return 0; } set { } } + public override int CNT_Sheen { get { return 0; } set { } } + #endregion + } + + class PokemonList + { + internal const int CAPACITY_DAYCARE = 1; + internal const int CAPACITY_PARTY = 6; + internal const int CAPACITY_STORED = 20; + internal const int CAPACITY_STORED_JP = 30; + + private bool Japanese; + + private int StringLength => Japanese ? PK1.STRLEN_J : PK1.STRLEN_U; + + internal static readonly byte[] EMPTY_LIST = { 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50 }; + public enum CapacityType + { + Daycare = CAPACITY_DAYCARE, + Party = CAPACITY_PARTY, + Stored = CAPACITY_STORED, + StoredJP = CAPACITY_STORED_JP, + Single + } + + public static int getEntrySize(CapacityType c) + { + return c == CapacityType.Single || c == CapacityType.Party + ? PKX.SIZE_1PARTY + : PKX.SIZE_1STORED; + } + + public static byte getCapacity(CapacityType c) + { + return c == CapacityType.Single ? (byte)1 : (byte)c; + } + + private byte[] getEmptyList(CapacityType c, bool is_JP = false) + { + int cap = getCapacity(c); + return new[] { (byte)0 }.Concat(Enumerable.Repeat((byte)0xFF, cap + 1)).Concat(Enumerable.Repeat((byte)0, getEntrySize(c) * cap)).Concat(Enumerable.Repeat((byte)0x50, (is_JP ? PK1.STRLEN_J : PK1.STRLEN_U) * 2 * cap)).ToArray(); + } + + public PokemonList(byte[] d, CapacityType c = CapacityType.Single, bool jp = false) + { + Japanese = jp; + Data = d ?? getEmptyList(c, Japanese); + Capacity = getCapacity(c); + Entry_Size = getEntrySize(c); + + if (Data.Length != DataSize) + { + Array.Resize(ref Data, DataSize); + } + + Pokemon = new PK1[Capacity]; + for (int i = 0; i < Capacity; i++) + { + int base_ofs = 2 + Capacity; + byte[] dat = Data.Skip(base_ofs + Entry_Size * i).Take(Entry_Size).ToArray(); + Pokemon[i] = new PK1(dat, null, jp); + Pokemon[i].OT_Name = PKX.getG1Str(Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * i).Take(StringLength).ToArray(), Japanese); + Pokemon[i].Nickname = PKX.getG1Str(Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * Capacity + StringLength * i).Take(StringLength).ToArray(), Japanese); + } + } + + public PokemonList(CapacityType c = CapacityType.Single, bool jp = false) + : this(null, c, jp) + { + Count = 1; + } + + public PokemonList(PK1 pk) + : this(CapacityType.Single, pk.Japanese) + { + this[0] = pk; + Count = 1; + } + + private readonly byte[] Data; + private readonly byte Capacity; + private readonly int Entry_Size; + + public byte Count + { + get { return Data[0]; } + set { Data[0] = value > Capacity ? Capacity : value; } + } + + public int GetCapacity() + { + return Capacity; + } + + public readonly PK1[] Pokemon; + + public PK1 this[int i] + { + get + { + if (i > Capacity || i < 0) throw new IndexOutOfRangeException($"Invalid PokemonList Access: {i}"); + return Pokemon[i]; + } + set + { + if (value == null) return; + Pokemon[i] = (PK1)value.Clone(); + } + } + + private void Update() + { + for (int i = 0; i < Count; i++) + { + Data[1 + i] = (byte)Pokemon[i].Species; + Array.Copy(Pokemon[i].Data, 0, Data, 2 + Capacity + Entry_Size * i, Entry_Size); + Array.Copy(PKX.setG1Str(Pokemon[i].OT_Name, Japanese), 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * i, StringLength); + Array.Copy(PKX.setG1Str(Pokemon[i].Nickname, Japanese), 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * Capacity + StringLength * i, StringLength); + } + Data[1 + Count] = byte.MaxValue; + } + + public byte[] GetBytes() + { + Update(); + return Data; + } + + private int DataSize => Capacity * (Entry_Size + 1 + 2 * StringLength) + 2; + + public static int GetDataLength(CapacityType c, bool jp = false) + { + return getCapacity(c) * (getEntrySize(c) + 1 + 2 * (jp ? PK1.STRLEN_J : PK1.STRLEN_U)) + 2; + } + } +} diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index 8aebbcbae..2020b083a 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -9,6 +9,11 @@ namespace PKHeX { public static class PKX { + internal const int SIZE_1ULIST = 69; + internal const int SIZE_1JLIST = 59; + internal const int SIZE_1PARTY = 40; + internal const int SIZE_1STORED = 33; + internal const int SIZE_3PARTY = 100; internal const int SIZE_3STORED = 80; internal const int SIZE_3BLOCK = 12; @@ -1617,5 +1622,21 @@ public static ushort getG4Item(ushort g3val) return 0xFFFF; return arr[g3val]; } + + public static byte setG1Char(ushort chr, bool jp) + { + throw new NotImplementedException(); + } + + public static string getG1Str(byte[] strdata, bool jp) + { + throw new NotImplementedException(); + } + + public static byte[] setG1Str(string str, bool jp) + { + throw new NotImplementedException(); + } + } } diff --git a/PKHeX/Util/ByteUtil.cs b/PKHeX/Util/ByteUtil.cs new file mode 100644 index 000000000..422ac6d9d --- /dev/null +++ b/PKHeX/Util/ByteUtil.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace PKHeX +{ + public partial class Util + { + /// + /// Swaps the Endianness of an int + /// Value to swap endianness of. + /// The endianness-swapped value. + internal static int SwapEndianness(int val) + { + return (int) SwapEndianness((uint) val); + } + + /// + /// Swaps the Endianness of a uint + /// Value to swap endianness of. + /// The endianness-swapped value. + internal static uint SwapEndianness(uint val) + { + return ((val & 0x000000FF) << 24) + | ((val & 0x0000FF00) << 8) + | ((val & 0x00FF0000) >> 8) + | ((val & 0xFF000000) >> 24); + } + + /// + /// Swaps the Endianness of a short + /// Value to swap endianness of. + /// The endianness-swapped value. + internal static int SwapEndianness(short val) + { + return (short)SwapEndianness((ushort)val); + } + + /// + /// Swaps the Endianness of a ushort + /// Value to swap endianness of. + /// The endianness-swapped value. + internal static ushort SwapEndianness(ushort val) + { + return (ushort) (((val & 0x00FF) << 8) | ((val & 0xFF00) >> 8)); + } + } +} From b5ec320b0392efe85118c33f1048c675cdad6859 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 27 Aug 2016 02:48:04 -0700 Subject: [PATCH 02/16] Cleanup, add Personal table for RBY --- PKHeX/PKM/PK1.cs | 6 +-- PKHeX/PKM/PKX.cs | 12 +++++ PKHeX/PersonalInfo/PersonalInfoG1.cs | 67 +++++++++++++++++++++++++ PKHeX/PersonalInfo/PersonalTable.cs | 6 +++ PKHeX/Properties/Resources.Designer.cs | 10 ++++ PKHeX/Properties/Resources.resx | 3 ++ PKHeX/Resources/byte/personal_rby | Bin 0 -> 4256 bytes PKHeX/Saves/SaveUtil.cs | 2 + 8 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 PKHeX/PersonalInfo/PersonalInfoG1.cs create mode 100644 PKHeX/Resources/byte/personal_rby diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index 89370505f..3b0fcb0f4 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -73,7 +73,7 @@ public override byte[] Encrypt() public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } #region Stored Attributes - public override int Species { get { return Data[0]; } set { } } + public override int Species { get { return PKX.getG1Species(Data[0]); } set { Data[0] = (byte)PKX.setG1Species(Data[0]); } } public override int Stat_HPCurrent { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x1); } } public int Status_Condition { get { return Data[4]; } set { Data[4] = (byte)value; } } @@ -148,8 +148,8 @@ public override bool getGenderIsValid() public override ushort Checksum { get { return 0; } set { } } public override int Language { get { return 0; } set { } } public override bool FatefulEncounter { get { return false; } set { } } - public override int TSV => 0; - public override int PSV => 0; + public override int TSV => 0x0000; + public override int PSV => 0xFFFF; public override int Characteristic => -1; public override byte MarkByte { get { return 0; } protected set { } } public override int CurrentFriendship { get { return 0; } set { } } diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index 2020b083a..ebdf74080 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -1623,6 +1623,18 @@ public static ushort getG4Item(ushort g3val) return arr[g3val]; } + public static int getG1Species(int raw_id) + { + int[] table = { 0x00, 0x70, 0x73, 0x20, 0x23, 0x15, 0x64, 0x22, 0x50, 0x02, 0x67, 0x6C, 0x66, 0x58, 0x5E, 0x1D, 0x1F, 0x68, 0x6F, 0x83, 0x3B, 0x97, 0x82, 0x5A, 0x48, 0x5C, 0x7B, 0x78, 0x09, 0x7F, 0x72, 0x00, 0x00, 0x3A, 0x5F, 0x16, 0x10, 0x4F, 0x40, 0x4B, 0x71, 0x43, 0x7A, 0x6A, 0x6B, 0x18, 0x2F, 0x36, 0x60, 0x4C, 0x00, 0x7E, 0x00, 0x7D, 0x52, 0x6D, 0x00, 0x38, 0x56, 0x32, 0x80, 0x00, 0x00, 0x00, 0x53, 0x30, 0x95, 0x00, 0x00, 0x00, 0x54, 0x3C, 0x7C, 0x92, 0x90, 0x91, 0x84, 0x34, 0x62, 0x00, 0x00, 0x00, 0x25, 0x26, 0x19, 0x1A, 0x00, 0x00, 0x93, 0x94, 0x8C, 0x8D, 0x74, 0x75, 0x00, 0x00, 0x1B, 0x1C, 0x8A, 0x8B, 0x27, 0x28, 0x85, 0x88, 0x87, 0x86, 0x42, 0x29, 0x17, 0x2E, 0x3D, 0x3E, 0x0D, 0x0E, 0x0F, 0x00, 0x55, 0x39, 0x33, 0x31, 0x57, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x44, 0x00, 0x37, 0x61, 0x2A, 0x96, 0x8F, 0x81, 0x00, 0x00, 0x59, 0x00, 0x63, 0x5B, 0x00, 0x65, 0x24, 0x6E, 0x35, 0x69, 0x00, 0x5D, 0x3F, 0x41, 0x11, 0x12, 0x79, 0x01, 0x03, 0x49, 0x00, 0x76, 0x77, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4E, 0x13, 0x14, 0x21, 0x1E, 0x4A, 0x89, 0x8E, 0x00, 0x51, 0x00, 0x00, 0x04, 0x07, 0x05, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2C, 0x2D, 0x45, 0x46, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + return table[raw_id]; + } + + public static int setG1Species(int dex_id) + { + int[] table = { 0x00, 0x99, 0x09, 0x9A, 0xB0, 0xB2, 0xB4, 0xB1, 0xB3, 0x1C, 0x7B, 0x7C, 0x7D, 0x70, 0x71, 0x72, 0x24, 0x96, 0x97, 0xA5, 0xA6, 0x05, 0x23, 0x6C, 0x2D, 0x54, 0x55, 0x60, 0x61, 0x0F, 0xA8, 0x10, 0x03, 0xA7, 0x07, 0x04, 0x8E, 0x52, 0x53, 0x64, 0x65, 0x6B, 0x82, 0xB9, 0xBA, 0xBB, 0x6D, 0x2E, 0x41, 0x77, 0x3B, 0x76, 0x4D, 0x90, 0x2F, 0x80, 0x39, 0x75, 0x21, 0x14, 0x47, 0x6E, 0x6F, 0x94, 0x26, 0x95, 0x6A, 0x29, 0x7E, 0xBC, 0xBD, 0xBE, 0x18, 0x9B, 0xA9, 0x27, 0x31, 0xA3, 0xA4, 0x25, 0x08, 0xAD, 0x36, 0x40, 0x46, 0x74, 0x3A, 0x78, 0x0D, 0x88, 0x17, 0x8B, 0x19, 0x93, 0x0E, 0x22, 0x30, 0x81, 0x4E, 0x8A, 0x06, 0x8D, 0x0C, 0x0A, 0x11, 0x91, 0x2B, 0x2C, 0x0B, 0x37, 0x8F, 0x12, 0x01, 0x28, 0x1E, 0x02, 0x5C, 0x5D, 0x9D, 0x9E, 0x1B, 0x98, 0x2A, 0x1A, 0x48, 0x35, 0x33, 0x1D, 0x3C, 0x85, 0x16, 0x13, 0x4C, 0x66, 0x69, 0x68, 0x67, 0xAA, 0x62, 0x63, 0x5A, 0x5B, 0xAB, 0x84, 0x4A, 0x4B, 0x49, 0x58, 0x59, 0x42, 0x83, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + return table[dex_id]; + } + public static byte setG1Char(ushort chr, bool jp) { throw new NotImplementedException(); diff --git a/PKHeX/PersonalInfo/PersonalInfoG1.cs b/PKHeX/PersonalInfo/PersonalInfoG1.cs new file mode 100644 index 000000000..f2ae6ff06 --- /dev/null +++ b/PKHeX/PersonalInfo/PersonalInfoG1.cs @@ -0,0 +1,67 @@ +using System; +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoG1 : PersonalInfo + { + protected PersonalInfoG1() { } + public const int SIZE = 0x1C; + public PersonalInfoG1(byte[] data) + { + if (data.Length != SIZE) + return; + + Data = data; + TMHM = getBits(Data.Skip(0x14).Take(0x8).ToArray()); + } + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x14); + return Data; + } + + public int DEX_ID { get { return Data[0x00]; } set { Data[0x00] = (byte)value; } } + public override int HP { get { return Data[0x01]; } set { Data[0x01] = (byte)value; } } + public override int ATK { get { return Data[0x02]; } set { Data[0x02] = (byte)value; } } + public override int DEF { get { return Data[0x03]; } set { Data[0x03] = (byte)value; } } + public override int SPE { get { return Data[0x04]; } set { Data[0x04] = (byte)value; } } + public int SPC { get { return Data[0x05]; } set { Data[0x05] = (byte)value; } } + public override int SPA { get { return SPC; } set { SPC = value; } } + public override int SPD { get { return SPC; } set { SPC = value; } } + public override int[] Types + { + get { return new int[] { Data[0x06], Data[0x07] }; } + set + { + if (value?.Length != 2) return; + Data[0x06] = (byte)value[0]; + Data[0x07] = (byte)value[1]; + } + } + public override int CatchRate { get { return Data[0x08]; } set { Data[0x08] = (byte)value; } } + public override int BaseEXP { get { return Data[0x09]; } set { Data[0x09] = (byte)value; } } + public int Move1 { get { return Data[0x0A]; } set { Data[0x0A] = (byte)value; } } + public int Move2 { get { return Data[0x0B]; } set { Data[0x0B] = (byte)value; } } + public int Move3 { get { return Data[0x0C]; } set { Data[0x0C] = (byte)value; } } + public int Move4 { get { return Data[0x0D]; } set { Data[0x0D] = (byte)value; } } + public override int EXPGrowth { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } } + + // Future game values, unused + public override int[] Items { get { return new[] { 0, 0 }; } set { } } + public override int[] EggGroups { get { return new[] { 0, 0 }; } set { } } + public override int[] Abilities { get { return new[] { 0, 0 }; } set { } } + public override int Gender { get { return 0; } set { } } + public override int HatchCycles { get { return 0; } set { } } + public override int BaseFriendship { get { return 0; } set { } } + public override int EscapeRate { get { return 0; } set { } } + public override int Color { get { return 0; } set { } } + private int EVYield { get { return 0; } set { } } + public override int EV_HP { get { return 0; } set { } } + public override int EV_ATK { get { return 0; } set { } } + public override int EV_DEF { get { return 0; } set { } } + public override int EV_SPE { get { return 0; } set { } } + public override int EV_SPA { get { return 0; } set { } } + public override int EV_SPD { get { return 0; } set { } } + } +} diff --git a/PKHeX/PersonalInfo/PersonalTable.cs b/PKHeX/PersonalInfo/PersonalTable.cs index 59d877243..942f1ab5c 100644 --- a/PKHeX/PersonalInfo/PersonalTable.cs +++ b/PKHeX/PersonalInfo/PersonalTable.cs @@ -15,6 +15,7 @@ public class PersonalTable internal static readonly PersonalTable FR = new PersonalTable(Properties.Resources.personal_fr, GameVersion.FR); internal static readonly PersonalTable E = new PersonalTable(Properties.Resources.personal_e, GameVersion.E); internal static readonly PersonalTable RS = new PersonalTable(Properties.Resources.personal_rs, GameVersion.RS); + internal static readonly PersonalTable RBY = new PersonalTable(Properties.Resources.personal_rby, GameVersion.RBY); private static byte[][] splitBytes(byte[] data, int size) { @@ -31,6 +32,7 @@ private PersonalTable(byte[] data, GameVersion format) int size = 0; switch (format) { + case GameVersion.RBY: size = PersonalInfoG1.SIZE;break; case GameVersion.RS: case GameVersion.E: case GameVersion.FR: @@ -52,6 +54,10 @@ private PersonalTable(byte[] data, GameVersion format) switch (format) { + case GameVersion.RBY: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoG1(entries[i]); + break; case GameVersion.RS: case GameVersion.E: case GameVersion.FR: diff --git a/PKHeX/Properties/Resources.Designer.cs b/PKHeX/Properties/Resources.Designer.cs index 1f66ae539..f71d2bdbb 100644 --- a/PKHeX/Properties/Resources.Designer.cs +++ b/PKHeX/Properties/Resources.Designer.cs @@ -15555,6 +15555,16 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_rby { + get { + object obj = ResourceManager.GetObject("personal_rby", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/PKHeX/Properties/Resources.resx b/PKHeX/Properties/Resources.resx index 67d0daac7..0d2026914 100644 --- a/PKHeX/Properties/Resources.resx +++ b/PKHeX/Properties/Resources.resx @@ -6391,4 +6391,7 @@ ..\Resources\img\box\swapBox.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\byte\personal_rby;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/PKHeX/Resources/byte/personal_rby b/PKHeX/Resources/byte/personal_rby new file mode 100644 index 0000000000000000000000000000000000000000..ccd7a53c07b5faaf351958bdef89fb92da377e52 GIT binary patch literal 4256 zcmZ{nYj7Lab;mETfC$5qDJcL6*fJz=WpPFFO4N$>QuIp166Er+6uEp{l3G5NkM)wE zNKi5;F7%)&gL)v=gH{~NjvCj9tjea2W1=i)l0_o`J=yaMs-=pdm zKX+_F_L4w}EC4&NuU4zNow(>8TUFOwrxBMG-!e}1zNi7qr``+JFPU~31%*OB>vrQZ z@_y%3mp>PLPM2mbPC8iRc(PP35r9qU)7^J_{J9tIu?Om#v^oOpZw+p&AqtG6rYAC& zOgks`(b$!dk$jv~*W9l0H{2Jd2U!>A^JZj3t4N8oC=K3+&}tsDqMTvH34^PBsIJpw zdBNg4LB@*KFtm?#Wl+f?GJa_D7<0eRhp?BWy%|)rk{Dx87=Pk3Q;-=6XHfW6BW@f& zywUWzIp~>PfO}ZWV5XQx)+9$>uV@$70;2LL$82!56Rj)dxk?sUqX%_owEghf4fnD2 zO|sN3A}fB&m_K~@=-LgvU>8i=eZyBwS9uXi?jnQrf^5bUCAP;uns-={i)-L}ScH^O z{fNA#(VyE3Y$DCv4DS;+!d^kOxxtB87OO~Jr+HPc3E*q1BZ^k9f zvT446V<;-QhwL92K0pIP3Cgn+i{~H@Pby@AqLdemcU#u&qw^VH!8G&IoKIo1vu7H~ z_}(*h&E|U3ljr6ZJZ0!%Ug0z)J6k$pQ1uIPGj0L4kYzMZhO&I*yq1JNtn+0PV9$xCg}LwB*euh z?g?c)Q7LdS+r@}E`~LI z@`SIT#eCD}@`_LY?y6ma>2pkvHQs5;_xtYo%xUP@OH7{&##hzdwSFJ-*w;R35f{=t zLKn+POgvd>fwf+bAmn{kKRfV#Xgjrk%r-rdW{+*z$_S8uGo||G z>Pt06se7j!kegPtrMgzqG?z>Ifsw5F@7ki=-feIXX_gzoE*I$K&04a(H?wa$geT3FHe$1MWU?A z_l;%ZY&+LqVCp5!@-fT#q%0~~M;;t_W1teusLd;Nsel(mhGbFE6S@$J4p#21yT`C3 z6V|Lt?;HO8v7x&9o$}XpX&WtaUM?eRMkMbZFb=M0q8Mt(Dzu$fWuKgpB^@`e?K|7< ztb?6GJxj4do?|hSLCr{{HPSKahohoRRPiSiV?{eefmf6aN_x(CLlmm~?A~)<*8Jp| zexk%we9p|x#|4p(2#}lKHhjaj5hpI_M~RQq>F2~=b_ed za$_Bl-EQe^!_hF`=*)#fOefQ^a%aBv669E#m2e{Fq0Y~=L+`K%1=|p^C#b5FmY!6?vMPg?{?171yF=TG@;BQP z!KyDzo$-(j3gdPs_mV@=%EK36IVw@=_$0=xN4o_Ln=q*n6*5`O1-X3CFJoeR+C>wJ|5LfpVL(4ozulZ6o8r>ih4ZS z1--E9N7Y&dvmPU}lO{uoBIPpzCIWhCdk2s<}_s zBAlEvb^VfF7#61aqN(c}#=nmI;9z~-PU&l1S1}ANYHn&KMDoHLMs~tJ z?VC$Ivy+Z2R4t2w7Ijnn-{_=#p<-tt4QwLKY8Y8_`Rul23#o6}+6rX}QQxC7m$ohD zAc<2WG`8EKr}WwyRO=tPkJZZI80PFYJgtwa|IwXd({Mi1ZZAtX#jGzc>(e!CT@m<1 z%g`Upd#@8TF$9|6XN|SBAJi4)W@EGr{lR4QiXdb%ZqG~~Nr>~6sh*m+;rO4=iz7%@ zrLa$Sd!#FdbMNW;PWI81c2lgu3zblX{;-dnZeP=3o&j<*eme;Lp^@cPF`Avte@~A; zMfdx6Gy@B!SyPd~@g>k3yYzoKaP#Sa*#q8&eJ(g2Ld`V667<`dZc<>Zi3Uuc*MLo~ zeh?8pENVR1{keexmxTa^PJIo|V6qkgb6AA@)ASSjzZimD!r5;)W@C_lt%@j%s@p5Q zqkpIBch!&LJ;0J_)+WoW7y84DLL&R#Q7mSCNuZbK@~W(8UnnH8&>N*!j22bxv9M== z1=39M2^xc8y&m$zp@m_8818*jsbg8H`UYxe)pteW_VT|lCbaMC;lks4?3*Uitiwn9 zWX(a%sD?4}{J|r`Pa$d(dij=f(26=Si`9sOQl8PDJ6I9<6V}BGd^qNy@QgmzezPOR zrh~8EIzO0$R2nBl&=MXpGyw(u{pJ~<);$NB=;jM?p5pP$==vL-cGaQ+OXX%s5cQC1 zF&Oc9q`xpan;MBlWjhgQ>CS0jy}ppbdfo2Z5n@!nQ+2_tOIJ!AvsT9wsE><9B&ZYo zlJRBFKlNS6e-PM2nrV!W)i}^ZKUr6OsXDcnO_um=sjUn>#k1mB88mT`bob{D`1^N& zCWQFyUjWm2MrQadkJ4*=)^exqEbP<1iE`X|WWb90Rh4k#SswgrPw32Jx7kkFddJVJb(q%^u3h{Cnvo@P_OrILD9302_qsW{;O*Y6zA8&>F zg3lN?8oQc3-RZc@-UPOv4b|70?5zHi=3tAh=RP*1aFP#tKb|mNZ{E{F7Xo{4V(P=o z5SL*_P-z~t^t67pe>CJj3TzXKr?eCnlqgRqivLTad~j^YfAkozK$?xnMD_Y?_ULKD z(VMCHz|6i(#Xr6r&p`)5u_%LWcK(;3d25+3J9ncUW*cBEI{069I~zjCm(<^`_19S_ zb1r~c(^M}ihTF#qx6QFs7KXU|T%Q_n4gzb2c`2TH2gHRK*g;%w>gV)T1Hg*RSt`|6zA5k`Bf)wx{Y2}n zHvg*$&`ZR;zaV;!W;9x{yK$7f(lw@XP(KmOA+r>$cShvLxd^Zi^mzc%R)lJ`$2eU?1s|gl}~Y!sPnH6}$7$!(+VNivQZ!vF}S| zT@S=8FIY9(2XCjTL|E`aT)dYIZ~N~%9zFS8WS>r6|LpoT7Co;Jjf{J()Mt=?#btpK z(+=WdzW**L0LQbf)ZZJgl$|JV1{dHnJ{R0jgTAF`iZbr9Qok|YI%<6;(3E11)Os&$ z4Pcgi_+cC*4Gl$&=6lSZC|#WU+_N5idv~)Siol-NUuyhK6P@1zce}z~Y(J&S+QU}- zTjR~qi7{Y3_TPafKKHQb;$T>bUGjLSe>5iAPAZ-3vt8yH?p}v?z)PC>L9PVIdcj_1 Lfsj$jmG6H6yy2#( literal 0 HcmV?d00001 diff --git a/PKHeX/Saves/SaveUtil.cs b/PKHeX/Saves/SaveUtil.cs index 9ad69d911..f4c54989b 100644 --- a/PKHeX/Saves/SaveUtil.cs +++ b/PKHeX/Saves/SaveUtil.cs @@ -18,6 +18,8 @@ public enum GameVersion SN = 28, MN = 29, // Game Groupings (SaveFile type) + RBY = 98, + GSC = 99, RS = 100, FRLG = 101, DP = 102, From e4ec1cb45fc479e7216cfb4e2dda2462521a6ddd Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 27 Aug 2016 02:56:15 -0700 Subject: [PATCH 03/16] Fix PK1 Species setting --- PKHeX/PKM/PK1.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index 3b0fcb0f4..ffe725310 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Linq.Expressions; namespace PKHeX { @@ -73,7 +74,19 @@ public override byte[] Encrypt() public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } #region Stored Attributes - public override int Species { get { return PKX.getG1Species(Data[0]); } set { Data[0] = (byte)PKX.setG1Species(Data[0]); } } + public override int Species + { + get { return PKX.getG1Species(Data[0]); } + set + { + // Before updating catch rate, check if Special Yellow Version Pikachu + if (!(PKX.getG1Species(Data[0]) == 25 && value == 25 && Catch_Rate == 163)) + Catch_Rate = PersonalTable.RBY[value].CatchRate; + Data[0] = (byte)PKX.setG1Species(value); + Type_A = PersonalTable.RBY[value].Types[0]; + Type_B = PersonalTable.RBY[value].Types[1]; + } + } public override int Stat_HPCurrent { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x1); } } public int Status_Condition { get { return Data[4]; } set { Data[4] = (byte)value; } } From b2342cddb9f6e9c1c636c0d2080d7c07adec4351 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 27 Aug 2016 04:33:21 -0700 Subject: [PATCH 04/16] SAV1 skeleton implementation --- PKHeX/PKHeX.csproj | 3 + PKHeX/PKM/PK1.cs | 8 +- PKHeX/PersonalInfo/PersonalInfoG1.cs | 16 +- PKHeX/Saves/Inventory.cs | 4 +- PKHeX/Saves/SAV1.cs | 312 +++++++++++++++++++++++++++ PKHeX/Saves/SaveFile.cs | 2 + PKHeX/Saves/SaveUtil.cs | 45 ++++ 7 files changed, 378 insertions(+), 12 deletions(-) create mode 100644 PKHeX/Saves/SAV1.cs diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index 4af47f6a3..db1be6497 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -90,6 +90,7 @@ + @@ -115,6 +116,7 @@ + @@ -462,6 +464,7 @@ + diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index ffe725310..07d4365a8 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -186,7 +186,7 @@ public override bool getGenderIsValid() #endregion } - class PokemonList + class PokemonList1 { internal const int CAPACITY_DAYCARE = 1; internal const int CAPACITY_PARTY = 6; @@ -225,7 +225,7 @@ private byte[] getEmptyList(CapacityType c, bool is_JP = false) return new[] { (byte)0 }.Concat(Enumerable.Repeat((byte)0xFF, cap + 1)).Concat(Enumerable.Repeat((byte)0, getEntrySize(c) * cap)).Concat(Enumerable.Repeat((byte)0x50, (is_JP ? PK1.STRLEN_J : PK1.STRLEN_U) * 2 * cap)).ToArray(); } - public PokemonList(byte[] d, CapacityType c = CapacityType.Single, bool jp = false) + public PokemonList1(byte[] d, CapacityType c = CapacityType.Single, bool jp = false) { Japanese = jp; Data = d ?? getEmptyList(c, Japanese); @@ -248,13 +248,13 @@ public PokemonList(byte[] d, CapacityType c = CapacityType.Single, bool jp = fal } } - public PokemonList(CapacityType c = CapacityType.Single, bool jp = false) + public PokemonList1(CapacityType c = CapacityType.Single, bool jp = false) : this(null, c, jp) { Count = 1; } - public PokemonList(PK1 pk) + public PokemonList1(PK1 pk) : this(CapacityType.Single, pk.Japanese) { this[0] = pk; diff --git a/PKHeX/PersonalInfo/PersonalInfoG1.cs b/PKHeX/PersonalInfo/PersonalInfoG1.cs index f2ae6ff06..7d4d8bbc0 100644 --- a/PKHeX/PersonalInfo/PersonalInfoG1.cs +++ b/PKHeX/PersonalInfo/PersonalInfoG1.cs @@ -47,6 +47,15 @@ public override int[] Types public int Move4 { get { return Data[0x0D]; } set { Data[0x0D] = (byte)value; } } public override int EXPGrowth { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } } + // EV Yields are just aliases for base stats in Gen I + public override int EV_HP { get { return HP; } set { } } + public override int EV_ATK { get { return ATK; } set { } } + public override int EV_DEF { get { return DEF; } set { } } + public override int EV_SPE { get { return SPE; } set { } } + public int EV_SPC { get { return SPC; } set { } } + public override int EV_SPA { get { return EV_SPC; } set { } } + public override int EV_SPD { get { return EV_SPC; } set { } } + // Future game values, unused public override int[] Items { get { return new[] { 0, 0 }; } set { } } public override int[] EggGroups { get { return new[] { 0, 0 }; } set { } } @@ -56,12 +65,5 @@ public override int[] Types public override int BaseFriendship { get { return 0; } set { } } public override int EscapeRate { get { return 0; } set { } } public override int Color { get { return 0; } set { } } - private int EVYield { get { return 0; } set { } } - public override int EV_HP { get { return 0; } set { } } - public override int EV_ATK { get { return 0; } set { } } - public override int EV_DEF { get { return 0; } set { } } - public override int EV_SPE { get { return 0; } set { } } - public override int EV_SPA { get { return 0; } set { } } - public override int EV_SPD { get { return 0; } set { } } } } diff --git a/PKHeX/Saves/Inventory.cs b/PKHeX/Saves/Inventory.cs index 036bb9e39..c49391632 100644 --- a/PKHeX/Saves/Inventory.cs +++ b/PKHeX/Saves/Inventory.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace PKHeX { @@ -23,7 +24,8 @@ public class InventoryPouch public readonly InventoryType Type; public readonly ushort[] LegalItems; public readonly int MaxCount; - private readonly int Offset; + public int Count => Items.Count(it => it.Count > 0); + public readonly int Offset; private readonly int PouchDataSize; public uint SecurityKey { private get; set; } // = 0 // Gen3 Only public InventoryItem[] Items; diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs new file mode 100644 index 000000000..30e0cad31 --- /dev/null +++ b/PKHeX/Saves/SAV1.cs @@ -0,0 +1,312 @@ +using System; +using System.Globalization; +using System.Linq; + +namespace PKHeX +{ + public sealed class SAV1 : SaveFile + { + public override string BAKName => $"{FileName} [{OT} ({Version})" +/* - {LastSavedTime}*/ "].bak"; + public override string Filter => "SAV File|*.sav"; + public override string Extension => ".sav"; + + public SAV1(byte[] data = null) + { + Data = data == null ? new byte[SaveUtil.SIZE_G1RAW] : (byte[])data.Clone(); + BAK = (byte[])Data.Clone(); + Exportable = !Data.SequenceEqual(new byte[Data.Length]); + + if (data == null) + Version = GameVersion.RBY; + else Version = SaveUtil.getIsG1SAV(Data); + if (Version == GameVersion.Invalid) + return; + + Japanese = SaveUtil.getIsG1SAVJ(data); + + OFS_PouchHeldItem = (Japanese ? 0x25C4 : 0x25C9); + OFS_PCItem = (Japanese ? 0x27DC : 0x27E6); + Personal = PersonalTable.RBY; + + if (!Exportable) + resetBoxes(); + } + + private const int SIZE_RESERVED = 0x10000; // unpacked box data + public override byte[] Write(bool DSV) + { + + setChecksums(); + return Data; + } + + + // Configuration + public override SaveFile Clone() { return new SAV1(Data); } + + public override int SIZE_STORED => PKX.SIZE_1STORED; + public override int SIZE_PARTY => PKX.SIZE_1PARTY; + public override PKM BlankPKM => new PK1(); + protected override Type PKMType => typeof(PK1); + + public override int MaxMoveID => 165; + public override int MaxSpeciesID => 151; + public override int MaxAbilityID => 0; + public override int MaxItemID => 255; + public override int MaxBallID => 0; + public override int MaxGameID => 99; // What do I set this to...? + + public override int BoxCount => Japanese ? 8 : 12; + public override int MaxEV => 65535; + public override int Generation => 1; + protected override int GiftCountMax => 0; + public override int OTLength => Japanese ? 5 : 10; + public override int NickLength => Japanese ? 5 : 10; + + public override bool HasParty => true; + + // Checksums + protected override void setChecksums() + { + int CHECKSUM_OFS = Japanese ? 0x3594 : 0x3523; + Data[CHECKSUM_OFS] = 0; + uint chksum = 0; + for (int i = 0x2598; i < CHECKSUM_OFS; i++) + { + chksum += Data[i]; + } + + chksum = ~chksum; + chksum &= 0xFF; + + Data[CHECKSUM_OFS] = (byte)chksum; + } + public override bool ChecksumsValid + { + get + { + int CHECKSUM_OFS = Japanese ? 0x3594 : 0x3523; + Data[CHECKSUM_OFS] = 0; + uint chksum = 0; + for (int i = 0x2598; i < CHECKSUM_OFS; i++) + { + chksum += Data[i]; + } + + chksum = ~chksum; + chksum &= 0xFF; + + return Data[CHECKSUM_OFS] == (byte)chksum; + } + } + public override string ChecksumInfo + { + get + { + return ChecksumsValid ? "Checksum valid." : "Checksum invalid"; + } + } + + // Trainer Info + public override GameVersion Version { get; protected set; } + + private int StringLength => Japanese ? PK1.STRLEN_J : PK1.STRLEN_U; + + public override string OT + { + get { return PKX.getG3Str(Data.Skip(0x2598).Take(StringLength).ToArray(), Japanese); } + set + { + byte[] strdata = PKX.setG1Str(value, Japanese); + if (strdata.Length > StringLength) + throw new ArgumentOutOfRangeException("OT Name too long for given save file."); + strdata.CopyTo(Data, 0x2598); + } + } + public override int Gender + { + get { return 0; } + set { } + } + public override ushort TID + { + get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, Japanese ? 0x25FB : 0x2605)); } + set { BitConverter.GetBytes(Util.SwapEndianness(value)).CopyTo(Data, Japanese ? 0x25FB : 0x2605); } + } + public override ushort SID + { + get { return 0; } + set { } + } + public override int PlayedHours + { + get { return BitConverter.ToUInt16(Data, Japanese ? 0x2CA0 : 0x2CED); } + set { BitConverter.GetBytes((ushort)value).CopyTo(Data, Japanese ? 0x2CA0 : 0x2CED); } + } + public override int PlayedMinutes + { + get { return Data[Japanese ? 0x2CA2 : 0x2CEF]; } + set { Data[Japanese ? 0x2CA2 : 0x2CEF] = (byte)value; } + } + public override int PlayedSeconds + { + get { return Data[Japanese ? 0x2CA3 : 0x2CF0]; } + set { Data[Japanese ? 0x2CA3 : 0x2CF0] = (byte)value; } + } + + public override uint Money + { + get { return uint.Parse((Util.SwapEndianness(BitConverter.ToUInt32(Data, Japanese ? 0x25EE : 0x25F3)) >> 8).ToString("X6")); } + set + { + BitConverter.GetBytes(Util.SwapEndianness(uint.Parse(value.ToString("000000"), NumberStyles.HexNumber))).Skip(1).ToArray().CopyTo(Data, Japanese ? 0x25EE : 0x25F3); + } + } + public uint Coin + { + get + { + return uint.Parse(Util.SwapEndianness(BitConverter.ToUInt16(Data, Japanese ? 0x2846 : 0x2850)).ToString("X4")); + } + set + { + BitConverter.GetBytes(Util.SwapEndianness(ushort.Parse(value.ToString("0000"), NumberStyles.HexNumber))).ToArray().CopyTo(Data, Japanese ? 0x2846 : 0x2850); + } + } + + private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs, LegalBerries; + public override InventoryPouch[] Inventory + { + get + { + ushort[] legalItems = LegalItems; + InventoryPouch[] pouch = + { + new InventoryPouch(InventoryType.Items, legalItems, 99, OFS_PouchHeldItem + 2, 20), + new InventoryPouch(InventoryType.Items, legalItems, 99, OFS_PCItem + 2, 50), + }; + foreach (var p in pouch) + { + p.getPouch(ref Data); + int ofs = 0; + for (int i = 0; i < p.Count; i++) + { + while (p.Items[ofs].Count == 0) + ofs++; + p.Items[i] = p.Items[ofs++]; + } + while (ofs < p.MaxCount) + p.Items[ofs++] = new InventoryItem { Count = 0, Index = 0 }; + } + return pouch; + } + set + { + foreach (var p in value) + { + int ofs = 0; + for (int i = 0; i < p.Count; i++) + { + while (p.Items[ofs].Count == 0) + ofs++; + p.Items[i] = p.Items[ofs++]; + } + while (ofs < p.MaxCount) + p.Items[ofs++] = new InventoryItem { Count = 0, Index = 0 }; + p.setPouch(ref Data); + Data[p.Offset - 2] = (byte)p.Count; + } + } + } + public override int getDaycareSlotOffset(int loc = 0, int slot = 0) + { + return Daycare; + } + public override ulong? getDaycareRNGSeed(int loc) + { + return null; + } + public override uint? getDaycareEXP(int loc = 0, int slot = 0) + { + return null; + } + public override bool? getDaycareOccupied(int loc, int slot) + { + return null; + } + public override void setDaycareEXP(int loc, int slot, uint EXP) + { + + } + public override void setDaycareOccupied(int loc, int slot, bool occupied) + { + + } + + // Storage + public override int PartyCount + { + get { return Data[Japanese ? 0x2ED5 : 0x2F2C]; } + protected set + { + Data[Japanese ? 0x2ED5 : 0x2F2C] = (byte)value; + } + } + public override int getBoxOffset(int box) + { + throw new NotImplementedException(); + } + public override int getPartyOffset(int slot) + { + throw new NotImplementedException(); + } + public override int CurrentBox + { + get { return Data[Japanese ? 0x2842 : 0x284C]; } + set { Data[Japanese ? 0x2842 : 0x284C] = (byte)value; } + } + public override int getBoxWallpaper(int box) + { + return 0; + } + public override string getBoxName(int box) + { + int boxNum = box + 1; + return $"Box {boxNum}"; + } + public override void setBoxName(int box, string value) + { + + } + public override PKM getPKM(byte[] data) + { + if (data.Length == PKX.SIZE_1JLIST || data.Length == PKX.SIZE_1ULIST) + return new PokemonList1(data, PokemonList1.CapacityType.Single, Japanese)[0]; + return new PK1(data); + } + public override byte[] decryptPKM(byte[] data) + { + return data; + } + + protected override void setDex(PKM pkm) + { + if (pkm.Species == 0) + return; + if (pkm.Species > MaxSpeciesID) + return; + if (Version == GameVersion.Unknown) + return; + + int bit = pkm.Species - 1; + int ofs = bit >> 3; + byte bitval = (byte)(1 << (bit % 7)); + + // Set the Captured Flag + Data[(Japanese ? 0x259E : 0x25A3) + ofs] |= bitval; + + // Set the Seen Flag + Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] |= bitval; + } + } +} diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs index 8db12ea12..84533da8c 100644 --- a/PKHeX/Saves/SaveFile.cs +++ b/PKHeX/Saves/SaveFile.cs @@ -58,6 +58,7 @@ public virtual byte[] Write(bool DSV) public bool E => Version == GameVersion.E; public bool FRLG => Version == GameVersion.FRLG; public bool RS => Version == GameVersion.RS; + public bool RBY => Version == GameVersion.RBY; public virtual int MaxMoveID => int.MaxValue; public virtual int MaxSpeciesID => int.MaxValue; @@ -260,6 +261,7 @@ public ushort[] EventConsts protected int OFS_PouchBalls { get; set; } = int.MinValue; protected int OFS_BattleItems { get; set; } = int.MinValue; protected int OFS_MailItems { get; set; } = int.MinValue; + protected int OFS_PCItem { get; set; } = int.MinValue; // Mystery Gift protected virtual bool[] MysteryGiftReceivedFlags { get { return null; } set { } } diff --git a/PKHeX/Saves/SaveUtil.cs b/PKHeX/Saves/SaveUtil.cs index f4c54989b..f10c94de9 100644 --- a/PKHeX/Saves/SaveUtil.cs +++ b/PKHeX/Saves/SaveUtil.cs @@ -45,6 +45,8 @@ public static class SaveUtil internal const int SIZE_G4RAW = 0x80000; internal const int SIZE_G3RAW = 0x20000; internal const int SIZE_G3RAWHALF = 0x10000; + internal const int SIZE_G1RAW = 0x8000; + internal const int SIZE_G1BAT = 0x802C; internal static readonly byte[] FOOTER_DSV = Encoding.ASCII.GetBytes("|-DESMUME SAVE-|"); @@ -53,6 +55,8 @@ public static class SaveUtil /// Version Identifier or Invalid if type cannot be determined. public static int getSAVGeneration(byte[] data) { + if (getIsG1SAV(data) != GameVersion.Invalid) + return 1; if (getIsG3SAV(data) != GameVersion.Invalid) return 3; if (getIsG4SAV(data) != GameVersion.Invalid) @@ -63,6 +67,47 @@ public static int getSAVGeneration(byte[] data) return 6; return -1; } + /// Determines the type of 1st gen save + /// Save data of which to determine the type + /// Version Identifier or Invalid if type cannot be determined. + public static GameVersion getIsG1SAV(byte[] data) + { + if (data.Length != SIZE_G1RAW && data.Length != SIZE_G1BAT) + return GameVersion.Invalid; + + // Check if it's not an american save or a japanese save + if (!(getIsG1SAVU(data) || getIsG1SAVJ(data))) + return GameVersion.Invalid; + // I can't actually detect which game version, because it's not stored anywhere. + // If you can think of anything to do here, please implement :) + return GameVersion.RBY; + } + /// Determines if 1st gen save is non-japanese + /// Save data of which to determine the region + /// True if a valid non-japanese save, False otherwise. + public static bool getIsG1SAVU(byte[] data) + { + foreach (int ofs in new[] { 0x2F2C, 0x30C0 }) + { + byte num_entries = data[ofs]; + if (num_entries > 20 || data[ofs + 1 + num_entries] != 0xFF) + return false; + } + return true; + } + /// Determines if 1st gen save is japanese + /// Save data of which to determine the region + /// True if a valid japanese save, False otherwise. + public static bool getIsG1SAVJ(byte[] data) + { + foreach (int ofs in new[] { 0x2ED5, 0x302D }) + { + byte num_entries = data[ofs]; + if (num_entries > 30 || data[ofs + 1 + num_entries] != 0xFF) + return false; + } + return true; + } /// Determines the type of 3th gen save /// Save data of which to determine the type /// Version Identifier or Invalid if type cannot be determined. From a4c70eec636ba2f052b784061fc387cf6dc3ed8f Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 27 Aug 2016 20:12:33 -0700 Subject: [PATCH 05/16] Basic G1 String conversion --- PKHeX/PKM/PKX.cs | 501 +++++++++++++++++++++++++++++++++++++++++++- PKHeX/Saves/SAV1.cs | 2 +- 2 files changed, 495 insertions(+), 8 deletions(-) diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index ebdf74080..1aef62f70 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using System.Drawing; using System.Drawing.Text; using System.Linq; using System.Runtime.InteropServices; +using System.Runtime.Remoting.Messaging; using PKHeX.Properties; namespace PKHeX @@ -1623,6 +1625,484 @@ public static ushort getG4Item(ushort g3val) return arr[g3val]; } + #region Gen 1 Character Tables + internal static Dictionary RBY2U_U => new Dictionary{ + {0x50, "\0"}, + {0x5D, "[TRAINER]"}, + {0x7F, " "}, + {0x80, "A"}, + {0x81, "B"}, + {0x82, "C"}, + {0x83, "D"}, + {0x84, "E"}, + {0x85, "F"}, + {0x86, "G"}, + {0x87, "H"}, + {0x88, "I"}, + {0x89, "J"}, + {0x8A, "K"}, + {0x8B, "L"}, + {0x8C, "M"}, + {0x8D, "N"}, + {0x8E, "O"}, + {0x8F, "P"}, + {0x90, "Q"}, + {0x91, "R"}, + {0x92, "S"}, + {0x93, "T"}, + {0x94, "U"}, + {0x95, "V"}, + {0x96, "W"}, + {0x97, "X"}, + {0x98, "Y"}, + {0x99, "Z"}, + {0x9A, "["}, + {0x9B, "\\"}, + {0x9C, "]"}, + {0x9D, "^"}, + {0x9E, "_"}, + {0x9F, "`"}, + {0xA0, "a"}, + {0xA1, "b"}, + {0xA2, "c"}, + {0xA3, "d"}, + {0xA4, "e"}, + {0xA5, "f"}, + {0xA6, "g"}, + {0xA7, "h"}, + {0xA8, "i"}, + {0xA9, "j"}, + {0xAA, "k"}, + {0xAB, "l"}, + {0xAC, "m"}, + {0xAD, "n"}, + {0xAE, "o"}, + {0xAF, "p"}, + {0xB0, "q"}, + {0xB1, "r"}, + {0xB2, "s"}, + {0xB3, "t"}, + {0xB4, "u"}, + {0xB5, "v"}, + {0xB6, "w"}, + {0xB7, "x"}, + {0xB8, "y"}, + {0xB9, "z"}, + {0xE1, "{"}, /* Pk */ + {0xE2, "}"}, /* Mn */ + {0xE3, "-"}, + {0xE6, "?"}, + {0xE7, "!"}, + {0xE8, "."}, + {0xEF, "♂"}, + {0xF2, "."}, + {0xF3, "/"}, + {0xF4, ","}, + {0xF5, "♀"}, + {0xF6, "0"}, + {0xF7, "1"}, + {0xF8, "2"}, + {0xF9, "3"}, + {0xFA, "4"}, + {0xFB, "5"}, + {0xFC, "6"}, + {0xFD, "7"}, + {0xFE, "8"}, + {0xFF, "9"} + }; + + internal static Dictionary U2RBY_U => new Dictionary { + {"\0", 0x50}, + {"[TRAINER]", 0x5D}, + {" ", 0x7F}, + {"A", 0x80}, + {"B", 0x81}, + {"C", 0x82}, + {"D", 0x83}, + {"E", 0x84}, + {"F", 0x85}, + {"G", 0x86}, + {"H", 0x87}, + {"I", 0x88}, + {"J", 0x89}, + {"K", 0x8A}, + {"L", 0x8B}, + {"M", 0x8C}, + {"N", 0x8D}, + {"O", 0x8E}, + {"P", 0x8F}, + {"Q", 0x90}, + {"R", 0x91}, + {"S", 0x92}, + {"T", 0x93}, + {"U", 0x94}, + {"V", 0x95}, + {"W", 0x96}, + {"X", 0x97}, + {"Y", 0x98}, + {"Z", 0x99}, + {"[", 0x9A}, + {"\\", 0x9B}, + {"]", 0x9C}, + {"^", 0x9D}, + {"_", 0x9E}, + {"`", 0x9F}, + {"a", 0xA0}, + {"b", 0xA1}, + {"c", 0xA2}, + {"d", 0xA3}, + {"e", 0xA4}, + {"f", 0xA5}, + {"g", 0xA6}, + {"h", 0xA7}, + {"i", 0xA8}, + {"j", 0xA9}, + {"k", 0xAA}, + {"l", 0xAB}, + {"m", 0xAC}, + {"n", 0xAD}, + {"o", 0xAE}, + {"p", 0xAF}, + {"q", 0xB0}, + {"r", 0xB1}, + {"s", 0xB2}, + {"t", 0xB3}, + {"u", 0xB4}, + {"v", 0xB5}, + {"w", 0xB6}, + {"x", 0xB7}, + {"y", 0xB8}, + {"z", 0xB9}, + {"{", 0xE1}, /* Pk */ + {"}", 0xE2}, /* Mn */ + {"-", 0xE3}, + {"?", 0xE6}, + {"!", 0xE7}, + {".", 0xE8}, + {"♂", 0xEF}, + {".", 0xF2}, + {"/", 0xF3}, + {",", 0xF4}, + {"♀", 0xF5}, + {"0", 0xF6}, + {"1", 0xF7}, + {"2", 0xF8}, + {"3", 0xF9}, + {"4", 0xFA}, + {"5", 0xFB}, + {"6", 0xFC}, + {"7", 0xFD}, + {"8", 0xFE}, + {"9", 0xFF} + }; + internal static Dictionary U2RBY_J => new Dictionary { + {"ガ", 0x05}, + {"ギ", 0x06}, + {"グ", 0x07}, + {"ゲ", 0x08}, + {"ゴ", 0x09}, + {"ザ", 0x0A}, + {"ジ", 0x0B}, + {"ズ", 0x0C}, + {"ゼ", 0x0D}, + {"ゾ", 0x0E}, + {"ダ", 0x0F}, + {"ヂ", 0x10}, + {"ヅ", 0x11}, + {"デ", 0x12}, + {"ド", 0x13}, + {"バ", 0x19}, + {"ビ", 0x1A}, + {"ブ", 0x1B}, + {"ボ", 0x1C}, + {"が", 0x26}, + {"ぎ", 0x27}, + {"ぐ", 0x28}, + {"げ", 0x29}, + {"ご", 0x2A}, + {"ざ", 0x2B}, + {"じ", 0x2C}, + {"ず", 0x2D}, + {"ぜ", 0x2E}, + {"ぞ", 0x2F}, + {"だ", 0x30}, + {"ぢ", 0x31}, + {"づ", 0x32}, + {"で", 0x33}, + {"ど", 0x34}, + {"ば", 0x3A}, + {"び", 0x3B}, + {"ぶ", 0x3C}, + {"べ", 0x3D}, + {"ぼ", 0x3E}, + {"パ", 0x40}, + {"ピ", 0x41}, + {"プ", 0x42}, + {"ポ", 0x43}, + {"ぱ", 0x44}, + {"ぴ", 0x45}, + {"ぷ", 0x46}, + {"ぺ", 0x47}, + {"ぽ", 0x48}, + {"トレーナー", 0x5D}, + {"ア", 0x80}, + {"イ", 0x81}, + {"ウ", 0x82}, + {"エ", 0x83}, + {"ォ", 0x84}, + {"カ", 0x85}, + {"キ", 0x86}, + {"ク", 0x87}, + {"ケ", 0x88}, + {"コ", 0x89}, + {"サ", 0x8A}, + {"シ", 0x8B}, + {"ス", 0x8C}, + {"セ", 0x8D}, + {"ソ", 0x8E}, + {"タ", 0x8F}, + {"チ", 0x90}, + {"ツ", 0x91}, + {"テ", 0x92}, + {"ト", 0x93}, + {"ナ", 0x94}, + {"ニ", 0x95}, + {"ヌ", 0x96}, + {"ネ", 0x97}, + {"ノ", 0x98}, + {"ハ", 0x99}, + {"ヒ", 0x9A}, + {"フ", 0x9B}, + {"ホ", 0x9C}, + {"マ", 0x9D}, + {"ミ", 0x9E}, + {"ム", 0x9F}, + {"メ", 0xA0}, + {"モ", 0xA1}, + {"ヤ", 0xA2}, + {"ユ", 0xA3}, + {"ヨ", 0xA4}, + {"ラ", 0xA5}, + {"ル", 0xA6}, + {"レ", 0xA7}, + {"ロ", 0xA8}, + {"ワ", 0xA9}, + {"ヲ", 0xAA}, + {"ン", 0xAB}, + {"ッ", 0xAC}, + {"ャ", 0xAD}, + {"ュ", 0xAE}, + {"ョ", 0xAF}, + {"ィ", 0xB0}, + {"あ", 0xB1}, + {"い", 0xB2}, + {"う", 0xB3}, + {"え", 0xB4}, + {"お", 0xB5}, + {"か", 0xB6}, + {"き", 0xB7}, + {"く", 0xB8}, + {"け", 0xB9}, + {"こ", 0xBA}, + {"さ", 0xBB}, + {"し", 0xBC}, + {"す", 0xBD}, + {"せ", 0xBE}, + {"そ", 0xBF}, + {"た", 0xC0}, + {"ち", 0xC1}, + {"つ", 0xC2}, + {"て", 0xC3}, + {"と", 0xC4}, + {"な", 0xC5}, + {"に", 0xC6}, + {"ぬ", 0xC7}, + {"ね", 0xC8}, + {"の", 0xC9}, + {"は", 0xCA}, + {"ひ", 0xCB}, + {"ふ", 0xCC}, + {"へ", 0xCD}, + {"ほ", 0xCE}, + {"ま", 0xCF}, + {"み", 0xD0}, + {"む", 0xD1}, + {"め", 0xD2}, + {"も", 0xD3}, + {"や", 0xD4}, + {"ゆ", 0xD5}, + {"よ", 0xD6}, + {"ら", 0xD7}, + {"り", 0xD8}, + {"る", 0xD9}, + {"れ", 0xDA}, + {"ろ", 0xDB}, + {"わ", 0xDC}, + {"を", 0xDD}, + {"ん", 0xDE}, + {"っ", 0xDF}, + {"ゃ", 0xE0}, + {"ゅ", 0xE1}, + {"ょ", 0xE2}, + {"ー", 0xE3}, + {"ァ", 0xE9}, + }; + + static Dictionary RBY2U_J => new Dictionary { + {0x05, "ガ"}, + {0x06, "ギ"}, + {0x07, "グ"}, + {0x08, "ゲ"}, + {0x09, "ゴ"}, + {0x0A, "ザ"}, + {0x0B, "ジ"}, + {0x0C, "ズ"}, + {0x0D, "ゼ"}, + {0x0E, "ゾ"}, + {0x0F, "ダ"}, + {0x10, "ヂ"}, + {0x11, "ヅ"}, + {0x12, "デ"}, + {0x13, "ド"}, + {0x19, "バ"}, + {0x1A, "ビ"}, + {0x1B, "ブ"}, + {0x1C, "ボ"}, + {0x26, "が"}, + {0x27, "ぎ"}, + {0x28, "ぐ"}, + {0x29, "げ"}, + {0x2A, "ご"}, + {0x2B, "ざ"}, + {0x2C, "じ"}, + {0x2D, "ず"}, + {0x2E, "ぜ"}, + {0x2F, "ぞ"}, + {0x30, "だ"}, + {0x31, "ぢ"}, + {0x32, "づ"}, + {0x33, "で"}, + {0x34, "ど"}, + {0x3A, "ば"}, + {0x3B, "び"}, + {0x3C, "ぶ"}, + {0x3D, "べ"}, + {0x3E, "ぼ"}, + {0x40, "パ"}, + {0x41, "ピ"}, + {0x42, "プ"}, + {0x43, "ポ"}, + {0x44, "ぱ"}, + {0x45, "ぴ"}, + {0x46, "ぷ"}, + {0x47, "ぺ"}, + {0x48, "ぽ"}, + {0x50, "\0"}, + {0x5D, "トレーナー"}, + {0x80, "ア"}, + {0x81, "イ"}, + {0x82, "ウ"}, + {0x83, "エ"}, + {0x84, "ォ"}, + {0x85, "カ"}, + {0x86, "キ"}, + {0x87, "ク"}, + {0x88, "ケ"}, + {0x89, "コ"}, + {0x8A, "サ"}, + {0x8B, "シ"}, + {0x8C, "ス"}, + {0x8D, "セ"}, + {0x8E, "ソ"}, + {0x8F, "タ"}, + {0x90, "チ"}, + {0x91, "ツ"}, + {0x92, "テ"}, + {0x93, "ト"}, + {0x94, "ナ"}, + {0x95, "ニ"}, + {0x96, "ヌ"}, + {0x97, "ネ"}, + {0x98, "ノ"}, + {0x99, "ハ"}, + {0x9A, "ヒ"}, + {0x9B, "フ"}, + {0x9C, "ホ"}, + {0x9D, "マ"}, + {0x9E, "ミ"}, + {0x9F, "ム"}, + {0xA0, "メ"}, + {0xA1, "モ"}, + {0xA2, "ヤ"}, + {0xA3, "ユ"}, + {0xA4, "ヨ"}, + {0xA5, "ラ"}, + {0xA6, "ル"}, + {0xA7, "レ"}, + {0xA8, "ロ"}, + {0xA9, "ワ"}, + {0xAA, "ヲ"}, + {0xAB, "ン"}, + {0xAC, "ッ"}, + {0xAD, "ャ"}, + {0xAE, "ュ"}, + {0xAF, "ョ"}, + {0xB0, "ィ"}, + {0xB1, "あ"}, + {0xB2, "い"}, + {0xB3, "う"}, + {0xB4, "え"}, + {0xB5, "お"}, + {0xB6, "か"}, + {0xB7, "き"}, + {0xB8, "く"}, + {0xB9, "け"}, + {0xBA, "こ"}, + {0xBB, "さ"}, + {0xBC, "し"}, + {0xBD, "す"}, + {0xBE, "せ"}, + {0xBF, "そ"}, + {0xC0, "た"}, + {0xC1, "ち"}, + {0xC2, "つ"}, + {0xC3, "て"}, + {0xC4, "と"}, + {0xC5, "な"}, + {0xC6, "に"}, + {0xC7, "ぬ"}, + {0xC8, "ね"}, + {0xC9, "の"}, + {0xCA, "は"}, + {0xCB, "ひ"}, + {0xCC, "ふ"}, + {0xCD, "へ"}, + {0xCE, "ほ"}, + {0xCF, "ま"}, + {0xD0, "み"}, + {0xD1, "む"}, + {0xD2, "め"}, + {0xD3, "も"}, + {0xD4, "や"}, + {0xD5, "ゆ"}, + {0xD6, "よ"}, + {0xD7, "ら"}, + {0xD8, "り"}, + {0xD9, "る"}, + {0xDA, "れ"}, + {0xDB, "ろ"}, + {0xDC, "わ"}, + {0xDD, "を"}, + {0xDE, "ん"}, + {0xDF, "っ"}, + {0xE0, "ゃ"}, + {0xE1, "ゅ"}, + {0xE2, "ょ"}, + {0xE3, "ー"}, + {0xE9, "ァ"}, + }; + #endregion + public static int getG1Species(int raw_id) { int[] table = { 0x00, 0x70, 0x73, 0x20, 0x23, 0x15, 0x64, 0x22, 0x50, 0x02, 0x67, 0x6C, 0x66, 0x58, 0x5E, 0x1D, 0x1F, 0x68, 0x6F, 0x83, 0x3B, 0x97, 0x82, 0x5A, 0x48, 0x5C, 0x7B, 0x78, 0x09, 0x7F, 0x72, 0x00, 0x00, 0x3A, 0x5F, 0x16, 0x10, 0x4F, 0x40, 0x4B, 0x71, 0x43, 0x7A, 0x6A, 0x6B, 0x18, 0x2F, 0x36, 0x60, 0x4C, 0x00, 0x7E, 0x00, 0x7D, 0x52, 0x6D, 0x00, 0x38, 0x56, 0x32, 0x80, 0x00, 0x00, 0x00, 0x53, 0x30, 0x95, 0x00, 0x00, 0x00, 0x54, 0x3C, 0x7C, 0x92, 0x90, 0x91, 0x84, 0x34, 0x62, 0x00, 0x00, 0x00, 0x25, 0x26, 0x19, 0x1A, 0x00, 0x00, 0x93, 0x94, 0x8C, 0x8D, 0x74, 0x75, 0x00, 0x00, 0x1B, 0x1C, 0x8A, 0x8B, 0x27, 0x28, 0x85, 0x88, 0x87, 0x86, 0x42, 0x29, 0x17, 0x2E, 0x3D, 0x3E, 0x0D, 0x0E, 0x0F, 0x00, 0x55, 0x39, 0x33, 0x31, 0x57, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x44, 0x00, 0x37, 0x61, 0x2A, 0x96, 0x8F, 0x81, 0x00, 0x00, 0x59, 0x00, 0x63, 0x5B, 0x00, 0x65, 0x24, 0x6E, 0x35, 0x69, 0x00, 0x5D, 0x3F, 0x41, 0x11, 0x12, 0x79, 0x01, 0x03, 0x49, 0x00, 0x76, 0x77, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4E, 0x13, 0x14, 0x21, 0x1E, 0x4A, 0x89, 0x8E, 0x00, 0x51, 0x00, 0x00, 0x04, 0x07, 0x05, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2C, 0x2D, 0x45, 0x46, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -1635,19 +2115,26 @@ public static int setG1Species(int dex_id) return table[dex_id]; } - public static byte setG1Char(ushort chr, bool jp) - { - throw new NotImplementedException(); - } - public static string getG1Str(byte[] strdata, bool jp) { - throw new NotImplementedException(); + Dictionary dict = jp ? RBY2U_J : RBY2U_U; + return strdata + .TakeWhile(b => dict.ContainsKey(b)) + .Select(b => dict[b]) + .TakeWhile(s => s != "\0") + .Aggregate("", (current, cur) => current + cur); } public static byte[] setG1Str(string str, bool jp) { - throw new NotImplementedException(); + Dictionary dict = jp ? U2RBY_J : U2RBY_U; + if (dict.ContainsKey(str)) // Handle "[TRAINER]" + return new[] {dict[str], dict["\0"]}; + return str + .TakeWhile(c => dict.ContainsKey(c.ToString())) + .Select(c => dict[c.ToString()]) + .Concat(new[] {dict["\0"]}) + .ToArray(); } } diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index 30e0cad31..e19cfe335 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -174,7 +174,7 @@ public uint Coin } } - private readonly ushort[] LegalItems, LegalKeyItems, LegalBalls, LegalTMHMs, LegalBerries; + private readonly ushort[] LegalItems; public override InventoryPouch[] Inventory { get From 4738a2c716c94ce6b20bc54015a6ef73f03b3986 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 28 Aug 2016 03:18:22 -0700 Subject: [PATCH 06/16] Initial support for SAV1 loading...warning: mostly broken --- PKHeX/MainWindow/Main.Designer.cs | 44 ++++----- PKHeX/MainWindow/Main.cs | 148 +++++++++++++++++++++-------- PKHeX/MainWindow/MainPK1.cs | 123 ++++++++++++++++++++++++ PKHeX/PKHeX.csproj | 3 + PKHeX/PKM/PK1.cs | 47 +++++++-- PKHeX/PKM/PKM.cs | 12 +-- PKHeX/PKM/PKX.cs | 40 ++++---- PKHeX/PersonalInfo/PersonalInfo.cs | 3 + PKHeX/Saves/Inventory.cs | 38 ++++++++ PKHeX/Saves/SAV1.cs | 125 +++++++++++++++++------- PKHeX/Saves/SaveFile.cs | 32 ++++--- PKHeX/Saves/SaveUtil.cs | 2 + 12 files changed, 482 insertions(+), 135 deletions(-) create mode 100644 PKHeX/MainWindow/MainPK1.cs diff --git a/PKHeX/MainWindow/Main.Designer.cs b/PKHeX/MainWindow/Main.Designer.cs index 51e1d7dc1..dbc698903 100644 --- a/PKHeX/MainWindow/Main.Designer.cs +++ b/PKHeX/MainWindow/Main.Designer.cs @@ -348,10 +348,10 @@ public void InitializeComponent() this.B_OpenOPowers = new System.Windows.Forms.Button(); this.B_OpenEventFlags = new System.Windows.Forms.Button(); this.B_OpenPokedex = new System.Windows.Forms.Button(); - this.B_OpenBerryField = new System.Windows.Forms.Button(); - this.B_OpenSecretBase = new System.Windows.Forms.Button(); - this.B_Pokeblocks = new System.Windows.Forms.Button(); this.B_LinkInfo = new System.Windows.Forms.Button(); + this.B_OpenBerryField = new System.Windows.Forms.Button(); + this.B_Pokeblocks = new System.Windows.Forms.Button(); + this.B_OpenSecretBase = new System.Windows.Forms.Button(); this.B_OpenPokepuffs = new System.Windows.Forms.Button(); this.B_OpenSuperTraining = new System.Windows.Forms.Button(); this.B_OpenHallofFame = new System.Windows.Forms.Button(); @@ -4454,6 +4454,16 @@ public void InitializeComponent() this.B_OpenPokedex.UseVisualStyleBackColor = true; this.B_OpenPokedex.Click += new System.EventHandler(this.B_OpenPokedex_Click); // + // B_LinkInfo + // + this.B_LinkInfo.Location = new System.Drawing.Point(96, 61); + this.B_LinkInfo.Name = "B_LinkInfo"; + this.B_LinkInfo.Size = new System.Drawing.Size(87, 23); + this.B_LinkInfo.TabIndex = 23; + this.B_LinkInfo.Text = "Link Data"; + this.B_LinkInfo.UseVisualStyleBackColor = true; + this.B_LinkInfo.Click += new System.EventHandler(this.B_LinkInfo_Click); + // // B_OpenBerryField // this.B_OpenBerryField.Location = new System.Drawing.Point(189, 61); @@ -4464,17 +4474,6 @@ public void InitializeComponent() this.B_OpenBerryField.UseVisualStyleBackColor = true; this.B_OpenBerryField.Click += new System.EventHandler(this.B_OpenBerryField_Click); // - // B_OpenSecretBase - // - this.B_OpenSecretBase.Location = new System.Drawing.Point(96, 90); - this.B_OpenSecretBase.Name = "B_OpenSecretBase"; - this.B_OpenSecretBase.Size = new System.Drawing.Size(87, 23); - this.B_OpenSecretBase.TabIndex = 21; - this.B_OpenSecretBase.Text = "Secret Base"; - this.B_OpenSecretBase.UseVisualStyleBackColor = true; - this.B_OpenSecretBase.Visible = false; - this.B_OpenSecretBase.Click += new System.EventHandler(this.B_OpenSecretBase_Click); - // // B_Pokeblocks // this.B_Pokeblocks.Location = new System.Drawing.Point(3, 90); @@ -4486,15 +4485,16 @@ public void InitializeComponent() this.B_Pokeblocks.Visible = false; this.B_Pokeblocks.Click += new System.EventHandler(this.B_OpenPokeblocks_Click); // - // B_LinkInfo + // B_OpenSecretBase // - this.B_LinkInfo.Location = new System.Drawing.Point(96, 61); - this.B_LinkInfo.Name = "B_LinkInfo"; - this.B_LinkInfo.Size = new System.Drawing.Size(87, 23); - this.B_LinkInfo.TabIndex = 23; - this.B_LinkInfo.Text = "Link Data"; - this.B_LinkInfo.UseVisualStyleBackColor = true; - this.B_LinkInfo.Click += new System.EventHandler(this.B_LinkInfo_Click); + this.B_OpenSecretBase.Location = new System.Drawing.Point(96, 90); + this.B_OpenSecretBase.Name = "B_OpenSecretBase"; + this.B_OpenSecretBase.Size = new System.Drawing.Size(87, 23); + this.B_OpenSecretBase.TabIndex = 21; + this.B_OpenSecretBase.Text = "Secret Base"; + this.B_OpenSecretBase.UseVisualStyleBackColor = true; + this.B_OpenSecretBase.Visible = false; + this.B_OpenSecretBase.Click += new System.EventHandler(this.B_OpenSecretBase_Click); // // B_OpenPokepuffs // diff --git a/PKHeX/MainWindow/Main.cs b/PKHeX/MainWindow/Main.cs index 5f63b6f04..1adc20910 100644 --- a/PKHeX/MainWindow/Main.cs +++ b/PKHeX/MainWindow/Main.cs @@ -710,7 +710,7 @@ private void openSAV(byte[] input, string path) SaveFile sav = SaveUtil.getVariantSAV(input); if (sav == null || sav.Version == GameVersion.Invalid) { Util.Error("Invalid save file loaded. Aborting.", path); return; } - if (sav.Generation <= 3) // Japanese Save files are different. Get isJapanese + if (sav.Generation == 3) // Japanese Save files are different. Get isJapanese { if (sav.Version == GameVersion.Unknown) { @@ -839,11 +839,60 @@ private void loadSAV(SaveFile sav, string path) TB_AbilityNumber.Visible = SAV.Generation >= 6 && DEV_Ability.Enabled; CB_Ability.Visible = !DEV_Ability.Enabled && SAV.Generation >= 3; + GB_ExtraBytes.Visible = SAV.Generation > 1; + GB_Markings.Visible = SAV.Generation > 2; + + Label_HeldItem.Visible = CB_HeldItem.Visible = SAV.Generation > 1; + Label_Total.Visible = TB_IVTotal.Visible = TB_EVTotal.Visible = L_Potential.Visible = + Label_HiddenPowerPrefix.Visible = CB_HPType.Visible = SAV.Generation > 1; + Label_CharacteristicPrefix.Visible = L_Characteristic.Visible = SAV.Generation > 1; + Label_ContestStats.Visible = Label_Cool.Visible = Label_Tough.Visible = Label_Smart.Visible = + Label_Sheen.Visible = Label_Beauty.Visible = Label_Cute.Visible = TB_Cool.Visible = TB_Tough.Visible = + TB_Smart.Visible = TB_Sheen.Visible = TB_Beauty.Visible = TB_Cute.Visible = SAV.Generation >= 3; + + if (1 <= sav.Generation && sav.Generation <= 2) + { + Label_SPD.Visible = TB_SPDEV.Visible = TB_SPDIV.Visible = Stat_SPD.Visible = false; + Label_SPA.Text = "Spc"; + TB_HPIV.ReadOnly = true; + Control[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV }; + foreach (MaskedTextBox ctrl in evControls) + { + ctrl.Mask = "00000"; + ctrl.Size = new Size(37, 20); + } + Control[] statControls = {Stat_HP, Stat_ATK, Stat_DEF, Stat_SPA, Stat_SPD, Stat_SPE}; + foreach (Control ctrl in statControls) + ctrl.Location = new Point(173, ctrl.Location.Y); + Label_Stats.Location = new Point(168, Label_Stats.Location.Y); + } + else + { + Label_SPD.Visible = TB_SPDEV.Visible = TB_SPDIV.Visible = Stat_SPD.Visible = true; + Label_SPA.Text = "SpA"; + TB_HPIV.ReadOnly = false; + Control[] evControls = { TB_SPAEV, TB_HPEV, TB_ATKEV, TB_DEFEV, TB_SPEEV, TB_SPDEV }; + foreach (MaskedTextBox ctrl in evControls) + { + ctrl.Mask = "000"; + ctrl.Size = new Size(31, 20); + } + Control[] statControls = { Stat_HP, Stat_ATK, Stat_DEF, Stat_SPA, Stat_SPD, Stat_SPE }; + foreach (Control ctrl in statControls) + ctrl.Location = new Point(167, ctrl.Location.Y); + Label_Stats.Location = new Point(162, Label_Stats.Location.Y); + } + // Recenter PKM SubEditors FLP_PKMEditors.Location = new Point((tabMain.TabPages[4].Width - FLP_PKMEditors.Width) / 2, FLP_PKMEditors.Location.Y); switch (SAV.Generation) { + case 1: + getFieldsfromPKM = populateFieldsPK1; + getPKMfromFields = preparePK1; + extraBytes = new byte[] {}; + break; case 3: getFieldsfromPKM = populateFieldsPK3; getPKMfromFields = preparePK3; @@ -886,10 +935,13 @@ private void loadSAV(SaveFile sav, string path) TB_Level.Visible = !HaX; // Load Extra Byte List - CB_ExtraBytes.Items.Clear(); - foreach (byte b in extraBytes) - CB_ExtraBytes.Items.Add("0x" + b.ToString("X2")); - CB_ExtraBytes.SelectedIndex = 0; + if (GB_ExtraBytes.Visible) + { + CB_ExtraBytes.Items.Clear(); + foreach (byte b in extraBytes) + CB_ExtraBytes.Items.Add("0x" + b.ToString("X2")); + CB_ExtraBytes.SelectedIndex = 0; + } // Refresh PK#->PK6 conversion info PKMConverter.updateConfig(SAV.SubRegion, SAV.Country, SAV.ConsoleRegion, SAV.OT, SAV.Gender); @@ -1116,12 +1168,15 @@ private void InitializeLanguage() } private void populateFilteredDataSources() { - string[] items = itemlist; - if (SAV.Generation == 3) - items = g3items; + if (SAV.Generation > 1) + { + string[] items = itemlist; + if (SAV.Generation == 3) + items = g3items; - ItemDataSource = Util.getCBList(items, (HaX ? Enumerable.Range(0, SAV.MaxItemID) : SAV.HeldItems.Select(i => (int)i)).ToArray()); - CB_HeldItem.DataSource = new BindingSource(ItemDataSource.Where(i => i.Value <= SAV.MaxItemID).ToList(), null); + ItemDataSource = Util.getCBList(items, (HaX ? Enumerable.Range(0, SAV.MaxItemID) : SAV.HeldItems.Select(i => (int)i)).ToArray()); + CB_HeldItem.DataSource = new BindingSource(ItemDataSource.Where(i => i.Value <= SAV.MaxItemID).ToList(), null); + } CB_Ball.DataSource = new BindingSource(BallDataSource.Where(b => b.Value <= SAV.MaxBallID).ToList(), null); CB_Species.DataSource = new BindingSource(SpeciesDataSource.Where(s => s.Value <= SAV.MaxSpeciesID).ToList(), null); @@ -1504,7 +1559,11 @@ private void updateEXPLevel(object sender, EventArgs e) } changingFields = false; if (fieldsLoaded) + { pkm.EXP = Util.ToUInt32(TB_EXP.Text); + if (SAV.Generation < 3) + pkm.Stat_Level = Util.ToInt32(TB_Level.Text); + } updateStats(); updateLegality(); } @@ -1534,8 +1593,8 @@ private void updateHPType(object sender, EventArgs e) private void updateIVs(object sender, EventArgs e) { if (changingFields || !fieldsInitialized) return; - if (sender != null && Util.ToInt32(((MaskedTextBox) sender).Text) > 31) - ((MaskedTextBox) sender).Text = "31"; + if (sender != null && Util.ToInt32(((MaskedTextBox) sender).Text) > SAV.MaxIV) + ((MaskedTextBox) sender).Text = SAV.MaxIV.ToString("00"); changingFields = true; @@ -1546,6 +1605,11 @@ private void updateIVs(object sender, EventArgs e) pkm.IV_SPE = Util.ToInt32(TB_SPEIV.Text); pkm.IV_SPA = Util.ToInt32(TB_SPAIV.Text); pkm.IV_SPD = Util.ToInt32(TB_SPDIV.Text); + + if (SAV.Generation < 3) + { + TB_HPIV.Text = pkm.IV_HP.ToString("00"); + } CB_HPType.SelectedValue = pkm.HPType; changingFields = false; @@ -1601,21 +1665,21 @@ private void updateRandomIVs(object sender, EventArgs e) if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift) { // Max IVs - TB_HPIV.Text = 31.ToString(); - TB_ATKIV.Text = 31.ToString(); - TB_DEFIV.Text = 31.ToString(); - TB_SPAIV.Text = 31.ToString(); - TB_SPDIV.Text = 31.ToString(); - TB_SPEIV.Text = 31.ToString(); + TB_HPIV.Text = SAV.MaxIV.ToString(); + TB_ATKIV.Text = SAV.MaxIV.ToString(); + TB_DEFIV.Text = SAV.MaxIV.ToString(); + TB_SPAIV.Text = SAV.MaxIV.ToString(); + TB_SPDIV.Text = SAV.MaxIV.ToString(); + TB_SPEIV.Text = SAV.MaxIV.ToString(); } else { - TB_HPIV.Text = (Util.rnd32() & 0x1F).ToString(); - TB_ATKIV.Text = (Util.rnd32() & 0x1F).ToString(); - TB_DEFIV.Text = (Util.rnd32() & 0x1F).ToString(); - TB_SPAIV.Text = (Util.rnd32() & 0x1F).ToString(); - TB_SPDIV.Text = (Util.rnd32() & 0x1F).ToString(); - TB_SPEIV.Text = (Util.rnd32() & 0x1F).ToString(); + TB_HPIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); + TB_ATKIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); + TB_DEFIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); + TB_SPAIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); + TB_SPDIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); + TB_SPEIV.Text = (Util.rnd32() % (SAV.MaxIV + 1)).ToString(); } changingFields = false; updateIVs(null, null); @@ -1624,7 +1688,7 @@ private void updateRandomEVs(object sender, EventArgs e) { if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift) { - // Max IVs + // Max EVs TB_HPEV.Text = 0.ToString(); TB_ATKEV.Text = 0.ToString(); TB_DEFEV.Text = 0.ToString(); @@ -1634,7 +1698,7 @@ private void updateRandomEVs(object sender, EventArgs e) } else { - byte[] evs = PKX.getRandomEVs(); + var evs = PKX.getRandomEVs(SAV.Generation); TB_HPEV.Text = evs[0].ToString(); TB_ATKEV.Text = evs[1].ToString(); TB_DEFEV.Text = evs[2].ToString(); @@ -2384,7 +2448,7 @@ public bool verifiedPKM() for (int i = 0; i < cba.Length; i++) { int back = cba[i].BackColor.ToArgb(); - if (back == SystemColors.Control.ToArgb() || back == 0 || + if (!cba[i].Visible || back == SystemColors.Control.ToArgb() || back == 0 || !(back != -1 & back != defaultControlWhite.ToArgb())) continue; if (i < 6) // Main Tab tabMain.SelectedIndex = 0; @@ -2396,7 +2460,7 @@ public bool verifiedPKM() } #endregion // Further logic checking - if (Convert.ToUInt32(TB_EVTotal.Text) > 510 && !CHK_HackedStats.Checked) + if (SAV.Generation >= 3 && Convert.ToUInt32(TB_EVTotal.Text) > 510 && !CHK_HackedStats.Checked) { tabMain.SelectedIndex = 2; goto invalid; } // If no errors detected... if (Util.getIndex(CB_Species) != 0) return true; @@ -2411,14 +2475,17 @@ public static string[] verifyPKMtoSAV(PKM pk) { // Check if PKM properties are outside of the valid range List errata = new List(); - if (pk.HeldItem > itemlist.Length) - errata.Add($"Item Index beyond range: {pk.HeldItem}"); - else + if (SAV.Generation > 1) { - if (pk.HeldItem > SAV.MaxItemID) - errata.Add($"Game can't obtain item: {itemlist[pk.HeldItem]}"); - if (!pk.CanHoldItem(SAV.HeldItems)) - errata.Add($"Game can't hold item: {itemlist[pk.HeldItem]}"); + if (pk.HeldItem > itemlist.Length) + errata.Add($"Item Index beyond range: {pk.HeldItem}"); + else + { + if (pk.HeldItem > SAV.MaxItemID) + errata.Add($"Game can't obtain item: {itemlist[pk.HeldItem]}"); + if (!pk.CanHoldItem(SAV.HeldItems)) + errata.Add($"Game can't hold item: {itemlist[pk.HeldItem]}"); + } } if (pk.Species > specieslist.Length) @@ -2911,9 +2978,16 @@ public void setPKXBoxes() int boxoffset = SAV.getBoxOffset(CB_BoxSelect.SelectedIndex); int boxbgval = SAV.getBoxWallpaper(CB_BoxSelect.SelectedIndex); PAN_Box.BackgroundImage = BoxWallpaper.getWallpaper(SAV, boxbgval); - for (int i = 0; i < 30; i++) - getSlotFiller(boxoffset + SAV.SIZE_STORED * i, SlotPictureBoxes[i]); + { + if (i < SAV.BoxSlotCount) + getSlotFiller(boxoffset + SAV.SIZE_STORED*i, SlotPictureBoxes[i]); + else + { + SlotPictureBoxes[i].Image = null; + SlotPictureBoxes[i].BackColor = Color.Gray; + } + } } // Reload Party diff --git a/PKHeX/MainWindow/MainPK1.cs b/PKHeX/MainWindow/MainPK1.cs new file mode 100644 index 000000000..f34be25cf --- /dev/null +++ b/PKHeX/MainWindow/MainPK1.cs @@ -0,0 +1,123 @@ +using System; + +namespace PKHeX +{ + public partial class Main + { + private void populateFieldsPK1() + { + PK1 pk1 = pkm as PK1; + if (pk1 == null) + return; + + // Do first + pk1.Stat_Level = PKX.getLevel(pk1.Species, pk1.EXP); + if (pk1.Stat_Level == 100) + pk1.EXP = PKX.getEXP(pk1.Stat_Level, pk1.Species); + + CB_Species.SelectedValue = pk1.Species; + TB_Level.Text = pk1.Stat_Level.ToString(); + TB_EXP.Text = pk1.EXP.ToString(); + + // Load rest + TB_TID.Text = pk1.TID.ToString("00000"); + TB_Nickname.Text = pk1.Nickname; + TB_OT.Text = pk1.OT_Name; + GB_OT.BackgroundImage = null; + + // Reset Label and ComboBox visibility, as well as non-data checked status. + Label_PKRS.Visible = false; + Label_PKRSdays.Visible = false; + + TB_HPIV.Text = pk1.IV_HP.ToString(); + TB_ATKIV.Text = pk1.IV_ATK.ToString(); + TB_DEFIV.Text = pk1.IV_DEF.ToString(); + TB_SPEIV.Text = pk1.IV_SPE.ToString(); + TB_SPAIV.Text = pk1.IV_SPA.ToString(); + + TB_HPEV.Text = pk1.EV_HP.ToString(); + TB_ATKEV.Text = pk1.EV_ATK.ToString(); + TB_DEFEV.Text = pk1.EV_DEF.ToString(); + TB_SPEEV.Text = pk1.EV_SPE.ToString(); + TB_SPAEV.Text = pk1.EV_SPA.ToString(); + + CB_Move1.SelectedValue = pk1.Move1; + CB_Move2.SelectedValue = pk1.Move2; + CB_Move3.SelectedValue = pk1.Move3; + CB_Move4.SelectedValue = pk1.Move4; + CB_PPu1.SelectedIndex = pk1.Move1_PPUps; + CB_PPu2.SelectedIndex = pk1.Move2_PPUps; + CB_PPu3.SelectedIndex = pk1.Move3_PPUps; + CB_PPu4.SelectedIndex = pk1.Move4_PPUps; + TB_PP1.Text = pk1.Move1_PP.ToString(); + TB_PP2.Text = pk1.Move2_PP.ToString(); + TB_PP3.Text = pk1.Move3_PP.ToString(); + TB_PP4.Text = pk1.Move4_PP.ToString(); + + updateStats(); + + TB_EXP.Text = pk1.EXP.ToString(); + } + private PKM preparePK1() + { + PK1 pk1 = pkm as PK1; + if (pk1 == null) + return null; + + pk1.Species = Util.getIndex(CB_Species); + pk1.TID = Util.ToInt32(TB_TID.Text); + pk1.EXP = Util.ToUInt32(TB_EXP.Text); + + pk1.EV_HP = Util.ToInt32(TB_HPEV.Text); + pk1.EV_ATK = Util.ToInt32(TB_ATKEV.Text); + pk1.EV_DEF = Util.ToInt32(TB_DEFEV.Text); + pk1.EV_SPE = Util.ToInt32(TB_SPEEV.Text); + pk1.EV_SPC = Util.ToInt32(TB_SPAEV.Text); + + pk1.Nickname = TB_Nickname.Text; + pk1.Move1 = Util.getIndex(CB_Move1); + pk1.Move2 = Util.getIndex(CB_Move2); + pk1.Move3 = Util.getIndex(CB_Move3); + pk1.Move4 = Util.getIndex(CB_Move4); + pk1.Move1_PP = Util.getIndex(CB_Move1) > 0 ? Util.ToInt32(TB_PP1.Text) : 0; + pk1.Move2_PP = Util.getIndex(CB_Move2) > 0 ? Util.ToInt32(TB_PP2.Text) : 0; + pk1.Move3_PP = Util.getIndex(CB_Move3) > 0 ? Util.ToInt32(TB_PP3.Text) : 0; + pk1.Move4_PP = Util.getIndex(CB_Move4) > 0 ? Util.ToInt32(TB_PP4.Text) : 0; + pk1.Move1_PPUps = Util.getIndex(CB_Move1) > 0 ? CB_PPu1.SelectedIndex : 0; + pk1.Move2_PPUps = Util.getIndex(CB_Move2) > 0 ? CB_PPu2.SelectedIndex : 0; + pk1.Move3_PPUps = Util.getIndex(CB_Move3) > 0 ? CB_PPu3.SelectedIndex : 0; + pk1.Move4_PPUps = Util.getIndex(CB_Move4) > 0 ? CB_PPu4.SelectedIndex : 0; + + pk1.IV_HP = Util.ToInt32(TB_HPIV.Text); + pk1.IV_ATK = Util.ToInt32(TB_ATKIV.Text); + pk1.IV_DEF = Util.ToInt32(TB_DEFIV.Text); + pk1.IV_SPE = Util.ToInt32(TB_SPEIV.Text); + pk1.IV_SPA = Util.ToInt32(TB_SPAIV.Text); + + + pk1.OT_Name = TB_OT.Text; + + // Toss in Party Stats + Array.Resize(ref pk1.Data, pk1.SIZE_PARTY); + pk1.Stat_Level = Util.ToInt32(TB_Level.Text); + pk1.Stat_HPCurrent = Util.ToInt32(Stat_HP.Text); + pk1.Stat_HPMax = Util.ToInt32(Stat_HP.Text); + pk1.Stat_ATK = Util.ToInt32(Stat_ATK.Text); + pk1.Stat_DEF = Util.ToInt32(Stat_DEF.Text); + pk1.Stat_SPE = Util.ToInt32(Stat_SPE.Text); + pk1.Stat_SPA = Util.ToInt32(Stat_SPA.Text); + pk1.Stat_SPD = Util.ToInt32(Stat_SPD.Text); + + if (HaX) + { + pk1.Stat_Level = (byte)Math.Min(Convert.ToInt32(MT_Level.Text), byte.MaxValue); + } + + // Fix Moves if a slot is empty + pk1.FixMoves(); + + pk1.RefreshChecksum(); + return pk1; + } + } +} diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index db1be6497..21ee6cfea 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -73,6 +73,9 @@ + + Form + Form diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index 07d4365a8..64f7307b6 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Linq.Expressions; @@ -10,6 +11,9 @@ class PK1 : PKM protected byte[] otname; protected byte[] nick; + public byte[] OT_Name_Raw => (byte[])otname.Clone(); + public byte[] Nickname_Raw => (byte[])nick.Clone(); + public sealed override int SIZE_PARTY => PKX.SIZE_1PARTY; public override int SIZE_STORED => PKX.SIZE_1STORED; internal const int STRLEN_J = 6; @@ -68,9 +72,15 @@ public override string OT_Name public override byte[] Encrypt() { - throw new NotImplementedException(); + // Oh god this is such total abuse of what this method is meant to do + // Please forgive me + return new PokemonList1(this).GetBytes(); } + // Please forgive me. + public override byte[] EncryptedPartyData => Encrypt().ToArray(); + public override byte[] EncryptedBoxData => Encrypt().ToArray(); + public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } #region Stored Attributes @@ -100,7 +110,7 @@ public override int Species public override int TID { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0xC)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0xC); } } public override uint EXP { - get { return Util.SwapEndianness(BitConverter.ToUInt32(Data, 0xE)) & 0x00FFFFFF; } + get { return (Util.SwapEndianness(BitConverter.ToUInt32(Data, 0xE)) >> 8) & 0x00FFFFFF; } set { Array.Copy(BitConverter.GetBytes(Util.SwapEndianness((value << 8) & 0xFFFFFF00)), 0, Data, 0xE, 3); } } public override int EV_HP { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x11)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x11); } } @@ -111,13 +121,13 @@ public override uint EXP public override int EV_SPA { get { return EV_SPC; } set { EV_SPC = value; } } public override int EV_SPD { get { return EV_SPC; } set { EV_SPC = value; } } public ushort DV16 { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1B)); } set { BitConverter.GetBytes(Util.SwapEndianness(value)).CopyTo(Data, 0x1B); } } - public override int IV_HP { get { return ((IV_ATK & 1) << 3) | ((IV_DEF & 1) << 2) | ((IV_SPD & 1) << 1) | ((IV_SPC & 1) << 0); } set { } } + public override int IV_HP { get { return ((IV_ATK & 1) << 3) | ((IV_DEF & 1) << 2) | ((IV_SPE & 1) << 1) | ((IV_SPC & 1) << 0); } set { } } public override int IV_ATK { get { return (DV16 >> 12) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 12)) | (ushort)((value > 0xF ? 0xF : value) << 12)); } } public override int IV_DEF { get { return (DV16 >> 8) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 8)) | (ushort)((value > 0xF ? 0xF : value) << 8)); } } public override int IV_SPE { get { return (DV16 >> 4) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 4)) | (ushort)((value > 0xF ? 0xF : value) << 4)); } } public int IV_SPC { get { return (DV16 >> 0) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 0)) | (ushort)((value > 0xF ? 0xF : value) << 0)); } } public override int IV_SPA { get { return IV_SPC; } set { IV_SPC = value; } } - public override int IV_SPD { get { return IV_SPC; } set { IV_SPC = value; } } + public override int IV_SPD { get { return IV_SPC; } set { } } public override int Move1_PP { get { return Data[0x1D] & 0x3F; } set { Data[0x1D] = (byte)((Data[0x1D] & 0xC0) | (value & 0x3F)); } } public override int Move2_PP { get { return Data[0x1E] & 0x3F; } set { Data[0x1E] = (byte)((Data[0x1E] & 0xC0) | (value & 0x3F)); } } public override int Move3_PP { get { return Data[0x1F] & 0x3F; } set { Data[0x1F] = (byte)((Data[0x1F] & 0xC0) | (value & 0x3F)); } } @@ -144,6 +154,23 @@ public override int Stat_Level public override int Stat_SPD { get { return Stat_SPC; } set { Stat_SPC = value; } } #endregion + public override ushort[] getStats(PersonalInfo p) + { + ushort[] Stats = new ushort[6]; + for (int i = 0; i < Stats.Length; i++) + { + ushort L = (ushort)Stat_Level; + ushort B = (ushort)p.Stats[i]; + ushort I = (ushort)IVs[i]; + ushort E = // Fixed formula via http://www.smogon.com/ingame/guides/rby_gsc_stats + (ushort)Math.Floor(Math.Min(255, Math.Floor(Math.Sqrt(Math.Max(0, EVs[i] - 1)) + 1)) / 4.0); + Stats[i] = (ushort)Math.Floor((2 * (B + I) + E) * L / 100.0 + 5); + } + Stats[0] += (ushort)(5 + Stat_Level); // HP + + return Stats; + } + #region Future, Unused Attributes public override bool getGenderIsValid() { @@ -157,7 +184,15 @@ public override bool getGenderIsValid() public override bool IsEgg { get { return false; } set { } } public override int Gender { get { return 0; } set { } } public override int HeldItem { get { return 0; } set { } } + + public override bool CanHoldItem(ushort[] ValidArray) + { + return false; + } + public override ushort Sanity { get { return 0; } set { } } + + public override bool ChecksumValid => true; public override ushort Checksum { get { return 0; } set { } } public override int Language { get { return 0; } set { } } public override bool FatefulEncounter { get { return false; } set { } } @@ -298,8 +333,8 @@ private void Update() { Data[1 + i] = (byte)Pokemon[i].Species; Array.Copy(Pokemon[i].Data, 0, Data, 2 + Capacity + Entry_Size * i, Entry_Size); - Array.Copy(PKX.setG1Str(Pokemon[i].OT_Name, Japanese), 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * i, StringLength); - Array.Copy(PKX.setG1Str(Pokemon[i].Nickname, Japanese), 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * Capacity + StringLength * i, StringLength); + Array.Copy(Pokemon[i].OT_Name_Raw, 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * i, StringLength); + Array.Copy(Pokemon[i].Nickname_Raw, 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * Capacity + StringLength * i, StringLength); } Data[1 + Count] = byte.MaxValue; } diff --git a/PKHeX/PKM/PKM.cs b/PKHeX/PKM/PKM.cs index 949efd682..517e36570 100644 --- a/PKHeX/PKM/PKM.cs +++ b/PKHeX/PKM/PKM.cs @@ -16,10 +16,10 @@ public abstract class PKM public int Box { get; set; } = -1; // Batch Editor public int Slot { get; set; } = -1; // Batch Editor - public byte[] EncryptedPartyData => Encrypt().Take(SIZE_PARTY).ToArray(); - public byte[] EncryptedBoxData => Encrypt().Take(SIZE_STORED).ToArray(); - public byte[] DecryptedPartyData => Write().Take(SIZE_PARTY).ToArray(); - public byte[] DecryptedBoxData => Write().Take(SIZE_STORED).ToArray(); + public virtual byte[] EncryptedPartyData => Encrypt().Take(SIZE_PARTY).ToArray(); + 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(); protected ushort CalculateChecksum() { @@ -250,7 +250,7 @@ public int GenNumber } public bool PKRS_Infected => PKRS_Strain > 0; public bool PKRS_Cured => PKRS_Days == 0 && PKRS_Strain > 0; - public bool ChecksumValid => Checksum == CalculateChecksum(); + public virtual bool ChecksumValid => Checksum == CalculateChecksum(); public int CurrentLevel => PKX.getLevel(Species, EXP); public bool MarkCircle { get { return (MarkByte & (1 << 0)) == 1 << 0; } set { MarkByte = (byte)(MarkByte & ~(1 << 0) | (value ? 1 << 0 : 0)); } } public bool MarkTriangle { get { return (MarkByte & (1 << 1)) == 1 << 1; } set { MarkByte = (byte)(MarkByte & ~(1 << 0) | (value ? 1 << 0 : 0)); } } @@ -391,7 +391,7 @@ public int PotentialRating } } - public ushort[] getStats(PersonalInfo p) + public virtual ushort[] getStats(PersonalInfo p) { int level = CurrentLevel; ushort[] Stats = new ushort[6]; diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index 1aef62f70..ee24587f5 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -4,7 +4,6 @@ using System.Drawing.Text; using System.Linq; using System.Runtime.InteropServices; -using System.Runtime.Remoting.Messaging; using PKHeX.Properties; namespace PKHeX @@ -13,7 +12,7 @@ public static class PKX { internal const int SIZE_1ULIST = 69; internal const int SIZE_1JLIST = 59; - internal const int SIZE_1PARTY = 40; + internal const int SIZE_1PARTY = 44; internal const int SIZE_1STORED = 33; internal const int SIZE_3PARTY = 100; @@ -195,19 +194,30 @@ public static bool getIsNicknamed(int species, string nick) public static readonly PersonalTable Personal = PersonalTable.AO; // Stat Fetching - public static byte[] getRandomEVs() + public static uint[] getRandomEVs(int Generation = 6) { - byte[] evs = new byte[6]; - do { - evs[0] = (byte)Math.Min(Util.rnd32() % 300, 252); // bias two to get maybe 252 - evs[1] = (byte)Math.Min(Util.rnd32() % 300, 252); - evs[2] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1]), 252); - evs[3] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1] - evs[2]), 252); - evs[4] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1] - evs[2] - evs[3]), 252); - evs[5] = (byte)Math.Min(510 - evs[0] - evs[1] - evs[2] - evs[3] - evs[4], 252); - } while (evs.Sum(b => b) > 510); // recalculate random EVs... - Util.Shuffle(evs); - return evs; + if (Generation > 2) + { + uint[] evs = new uint[6]; + do + { + evs[0] = (byte)Math.Min(Util.rnd32() % 300, 252); // bias two to get maybe 252 + evs[1] = (byte)Math.Min(Util.rnd32() % 300, 252); + evs[2] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1]), 252); + evs[3] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1] - evs[2]), 252); + evs[4] = (byte)Math.Min(Util.rnd32() % (510 - evs[0] - evs[1] - evs[2] - evs[3]), 252); + evs[5] = (byte)Math.Min(510 - evs[0] - evs[1] - evs[2] - evs[3] - evs[4], 252); + } while (evs.Sum(b => b) > 510); // recalculate random EVs... + Util.Shuffle(evs); + return evs; + } + else + { + uint[] evs = new uint[6]; + for (int i = 0; i < evs.Length; i++) + evs[i] = Util.rnd32()%0x10000; + return evs; + } } public static int getLevel(int species, uint exp) { @@ -1693,7 +1703,6 @@ public static ushort getG4Item(ushort g3val) {0xE3, "-"}, {0xE6, "?"}, {0xE7, "!"}, - {0xE8, "."}, {0xEF, "♂"}, {0xF2, "."}, {0xF3, "/"}, @@ -1778,7 +1787,6 @@ public static ushort getG4Item(ushort g3val) {"-", 0xE3}, {"?", 0xE6}, {"!", 0xE7}, - {".", 0xE8}, {"♂", 0xEF}, {".", 0xF2}, {"/", 0xF3}, diff --git a/PKHeX/PersonalInfo/PersonalInfo.cs b/PKHeX/PersonalInfo/PersonalInfo.cs index 10e76c4f1..fa5abb10d 100644 --- a/PKHeX/PersonalInfo/PersonalInfo.cs +++ b/PKHeX/PersonalInfo/PersonalInfo.cs @@ -10,6 +10,9 @@ public abstract class PersonalInfo public abstract int SPE { get; set; } public abstract int SPA { get; set; } public abstract int SPD { get; set; } + + public int[] Stats => new[] { HP, ATK, DEF, SPE, SPA, SPD }; + public abstract int EV_HP { get; set; } public abstract int EV_ATK { get; set; } public abstract int EV_DEF { get; set; } diff --git a/PKHeX/Saves/Inventory.cs b/PKHeX/Saves/Inventory.cs index c49391632..cc2ab1281 100644 --- a/PKHeX/Saves/Inventory.cs +++ b/PKHeX/Saves/Inventory.cs @@ -63,5 +63,43 @@ public void setPouch(ref byte[] Data) BitConverter.GetBytes((ushort)((ushort)Items[i].Count ^ (ushort)SecurityKey)).CopyTo(Data, Offset + i*4 + 2); } } + + public void getPouchG1(ref byte[] Data) + { + InventoryItem[] items = new InventoryItem[PouchDataSize]; + int numStored = Data[Offset]; + for (int i = 0; i < numStored; i++) + { + items[i] = new InventoryItem + { + Index = Data[Offset + i * 2 + 1], + Count = Data[Offset + i * 2 + 2] + }; + } + for (int i = numStored; i < items.Length; i++) + { + items[i] = new InventoryItem + { + Index = 0, + Count = 0 + }; + } + Items = items; + + } + + public void setPouchG1(ref byte[] Data) + { + if (Items.Length != PouchDataSize) + throw new ArgumentException("Item array length does not match original pouch size."); + + for (int i = 0; i < Items.Length; i++) + { + Data[Offset + i * 2 + 1] = (byte)Items[i].Index; + Data[Offset + i * 2 + 2] = (byte)Items[i].Count; + } + Data[Offset] = (byte) Count; + Data[Offset + 1 + 2*Count] = 0xFF; + } } } diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index e19cfe335..bc98a5600 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Globalization; using System.Linq; @@ -22,21 +23,83 @@ public SAV1(byte[] data = null) if (Version == GameVersion.Invalid) return; - Japanese = SaveUtil.getIsG1SAVJ(data); + Box = Data.Length; + Array.Resize(ref Data, Data.Length + SIZE_RESERVED); + Party = getPartyOffset(0); - OFS_PouchHeldItem = (Japanese ? 0x25C4 : 0x25C9); - OFS_PCItem = (Japanese ? 0x27DC : 0x27E6); + Japanese = SaveUtil.getIsG1SAVJ(data); Personal = PersonalTable.RBY; + // Stash boxes after the save file's end. + byte[] TempBox = new byte[SIZE_BOX]; + for (int i = 0; i < BoxCount; i++) + { + if (i < BoxCount / 2) + Array.Copy(Data, 0x4000 + i * TempBox.Length, TempBox, 0, TempBox.Length); + else + Array.Copy(Data, 0x6000 + (i - BoxCount / 2) * TempBox.Length, TempBox, 0, TempBox.Length); + PokemonList1 PL1 = new PokemonList1(TempBox, Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + for (int j = 0; j < PL1.Pokemon.Length; j++) + { + if (j < PL1.Count) + { + byte[] pkDat = new PokemonList1(PL1[j]).GetBytes(); + pkDat.CopyTo(Data, Data.Length - SIZE_RESERVED + i * SIZE_BOX + j * SIZE_STORED); + } + else + { + byte[] pkDat = new byte[PokemonList1.GetDataLength(PokemonList1.CapacityType.Single, Japanese)]; + pkDat.CopyTo(Data, Data.Length - SIZE_RESERVED + i * SIZE_BOX + j * SIZE_STORED); + } + } + } + + Array.Copy(Data, Japanese ? 0x302D : 0x30C0, TempBox, 0, TempBox.Length); + PokemonList1 curBoxPL = new PokemonList1(TempBox, Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + for (int i = 0; i < curBoxPL.Pokemon.Length; i++) + { + if (i < curBoxPL.Count) + { + byte[] pkDat = new PokemonList1(curBoxPL[i]).GetBytes(); + pkDat.CopyTo(Data, Data.Length - SIZE_RESERVED + CurrentBox * SIZE_BOX + i * SIZE_STORED); + } + else + { + byte[] pkDat = new byte[PokemonList1.GetDataLength(PokemonList1.CapacityType.Single, Japanese)]; + pkDat.CopyTo(Data, Data.Length - SIZE_RESERVED + CurrentBox * SIZE_BOX + i * SIZE_STORED); + } + } + + byte[] TempParty = new byte[PokemonList1.GetDataLength(PokemonList1.CapacityType.Party, Japanese)]; + Array.Copy(Data, Japanese ? 0x2ED5 : 0x2F2C, TempParty, 0, TempParty.Length); + PokemonList1 partyList = new PokemonList1(TempParty, PokemonList1.CapacityType.Party, Japanese); + for (int i = 0; i < partyList.Pokemon.Length; i++) + { + if (i < partyList.Count) + { + byte[] pkDat = new PokemonList1(partyList[i]).GetBytes(); + pkDat.CopyTo(Data, getPartyOffset(i)); + } + else + { + byte[] pkDat = new byte[PokemonList1.GetDataLength(PokemonList1.CapacityType.Single, Japanese)]; + pkDat.CopyTo(Data, getPartyOffset(i)); + } + } + + File.WriteAllBytes("temp.sav", Data); + + if (!Exportable) resetBoxes(); } - private const int SIZE_RESERVED = 0x10000; // unpacked box data + private const int SIZE_RESERVED = 0x8000; // unpacked box data public override byte[] Write(bool DSV) { - + // TODO: Implement Box Data Relocation setChecksums(); + Array.Resize(ref Data, Data.Length - SIZE_RESERVED); return Data; } @@ -44,9 +107,11 @@ public override byte[] Write(bool DSV) // Configuration public override SaveFile Clone() { return new SAV1(Data); } - public override int SIZE_STORED => PKX.SIZE_1STORED; - public override int SIZE_PARTY => PKX.SIZE_1PARTY; - public override PKM BlankPKM => new PK1(); + public override int SIZE_STORED => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; + public override int SIZE_PARTY => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; + + public int SIZE_BOX => PokemonList1.GetDataLength(Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + public override PKM BlankPKM => new PK1(null, null, Japanese); protected override Type PKMType => typeof(PK1); public override int MaxMoveID => 165; @@ -58,6 +123,7 @@ public override byte[] Write(bool DSV) public override int BoxCount => Japanese ? 8 : 12; public override int MaxEV => 65535; + public override int MaxIV => 15; public override int Generation => 1; protected override int GiftCountMax => 0; public override int OTLength => Japanese ? 5 : 10; @@ -114,7 +180,7 @@ public override string ChecksumInfo public override string OT { - get { return PKX.getG3Str(Data.Skip(0x2598).Take(StringLength).ToArray(), Japanese); } + get { return PKX.getG1Str(Data.Skip(0x2598).Take(StringLength).ToArray(), Japanese); } set { byte[] strdata = PKX.setG1Str(value, Japanese); @@ -174,7 +240,7 @@ public uint Coin } } - private readonly ushort[] LegalItems; + private readonly ushort[] LegalItems = Enumerable.Range(1, 255).Select(i => (ushort)i).ToArray(); public override InventoryPouch[] Inventory { get @@ -182,21 +248,12 @@ public override InventoryPouch[] Inventory ushort[] legalItems = LegalItems; InventoryPouch[] pouch = { - new InventoryPouch(InventoryType.Items, legalItems, 99, OFS_PouchHeldItem + 2, 20), - new InventoryPouch(InventoryType.Items, legalItems, 99, OFS_PCItem + 2, 50), + new InventoryPouch(InventoryType.Items, legalItems, 99, (Japanese ? 0x25C4 : 0x25C9), 20), + new InventoryPouch(InventoryType.Items, legalItems, 99, (Japanese ? 0x27DC : 0x27E6), 50), }; foreach (var p in pouch) { - p.getPouch(ref Data); - int ofs = 0; - for (int i = 0; i < p.Count; i++) - { - while (p.Items[ofs].Count == 0) - ofs++; - p.Items[i] = p.Items[ofs++]; - } - while (ofs < p.MaxCount) - p.Items[ofs++] = new InventoryItem { Count = 0, Index = 0 }; + p.getPouchG1(ref Data); } return pouch; } @@ -211,10 +268,9 @@ public override InventoryPouch[] Inventory ofs++; p.Items[i] = p.Items[ofs++]; } - while (ofs < p.MaxCount) + while (ofs < p.Items.Length) p.Items[ofs++] = new InventoryItem { Count = 0, Index = 0 }; - p.setPouch(ref Data); - Data[p.Offset - 2] = (byte)p.Count; + p.setPouchG1(ref Data); } } } @@ -244,6 +300,9 @@ public override void setDaycareOccupied(int loc, int slot, bool occupied) } // Storage + + public override int BoxSlotCount => Japanese ? 30 : 20; + public override int PartyCount { get { return Data[Japanese ? 0x2ED5 : 0x2F2C]; } @@ -254,16 +313,16 @@ protected set } public override int getBoxOffset(int box) { - throw new NotImplementedException(); + return Data.Length - SIZE_RESERVED + box * SIZE_BOX; } public override int getPartyOffset(int slot) { - throw new NotImplementedException(); + return Data.Length - SIZE_RESERVED + BoxCount * SIZE_BOX + slot * SIZE_STORED; } public override int CurrentBox { - get { return Data[Japanese ? 0x2842 : 0x284C]; } - set { Data[Japanese ? 0x2842 : 0x284C] = (byte)value; } + get { return Data[Japanese ? 0x2842 : 0x284C] & 0x7F; } + set { Data[Japanese ? 0x2842 : 0x284C] = (byte)((Data[Japanese ? 0x2842 : 0x284C] & 0x80) | (value & 0x7F)); } } public override int getBoxWallpaper(int box) { @@ -271,16 +330,16 @@ public override int getBoxWallpaper(int box) } public override string getBoxName(int box) { - int boxNum = box + 1; - return $"Box {boxNum}"; + return string.Format("Box {0}", box + 1); } public override void setBoxName(int box, string value) { - + // Don't allow for custom box names } + public override PKM getPKM(byte[] data) { - if (data.Length == PKX.SIZE_1JLIST || data.Length == PKX.SIZE_1ULIST) + if (data.Length == SIZE_STORED) return new PokemonList1(data, PokemonList1.CapacityType.Single, Japanese)[0]; return new PK1(data); } diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs index 84533da8c..fdc5c86d5 100644 --- a/PKHeX/Saves/SaveFile.cs +++ b/PKHeX/Saves/SaveFile.cs @@ -29,6 +29,7 @@ public abstract class SaveFile public abstract int SIZE_STORED { get; } public abstract int SIZE_PARTY { get; } public abstract int MaxEV { get; } + public virtual int MaxIV => 31; public ushort[] HeldItems { get; protected set; } // General SAV Properties @@ -128,13 +129,13 @@ public PKM[] BoxData { get { - PKM[] data = new PKM[BoxCount*30]; + PKM[] data = new PKM[BoxCount*BoxSlotCount]; for (int i = 0; i < data.Length; i++) { - data[i] = getStoredSlot(getBoxOffset(i/30) + SIZE_STORED*(i%30)); - data[i].Identifier = $"{getBoxName(i/30)}:{(i%30 + 1).ToString("00")}"; - data[i].Box = i/30 + 1; - data[i].Slot = i%30 + 1; + data[i] = getStoredSlot(getBoxOffset(i/BoxSlotCount) + SIZE_STORED*(i%BoxSlotCount)); + data[i].Identifier = $"{getBoxName(i/BoxSlotCount)}:{(i%BoxSlotCount + 1).ToString("00")}"; + data[i].Box = i/BoxSlotCount + 1; + data[i].Slot = i%BoxSlotCount + 1; } return data; } @@ -142,13 +143,13 @@ public PKM[] BoxData { if (value == null) throw new ArgumentNullException(); - if (value.Length != BoxCount*30) - throw new ArgumentException($"Expected {BoxCount*30}, got {value.Length}"); + if (value.Length != BoxCount*BoxSlotCount) + throw new ArgumentException($"Expected {BoxCount*BoxSlotCount}, got {value.Length}"); if (value.Any(pk => PKMType != pk.GetType())) throw new ArgumentException($"Not {PKMType} array."); for (int i = 0; i < value.Length; i++) - setStoredSlot(value[i], getBoxOffset(i/30) + SIZE_STORED*(i%30)); + setStoredSlot(value[i], getBoxOffset(i/BoxSlotCount) + SIZE_STORED*(i%BoxSlotCount)); } } public PKM[] PartyData @@ -330,6 +331,7 @@ public virtual MysteryGiftAlbum GiftAlbum public abstract void setDaycareOccupied(int loc, int slot, bool occupied); // Storage + public virtual int BoxSlotCount => 30; public PKM getPartySlot(int offset) { return getPKM(decryptPKM(getData(offset, SIZE_PARTY))); @@ -417,9 +419,9 @@ public void deletePartySlot(int slot) public void sortBoxes(int BoxStart = 0, int BoxEnd = -1) { PKM[] BD = BoxData; - var Section = BD.Skip(BoxStart*30); + var Section = BD.Skip(BoxStart*BoxSlotCount); if (BoxEnd > BoxStart) - Section = Section.Take(30*(BoxEnd - BoxStart)); + Section = Section.Take(BoxSlotCount*(BoxEnd - BoxStart)); var Sorted = Section .OrderBy(p => p.Species == 0) // empty slots at end @@ -427,7 +429,7 @@ public void sortBoxes(int BoxStart = 0, int BoxEnd = -1) .ThenBy(p => p.Species) // species sorted .ThenBy(p => p.IsNicknamed).ToArray(); - Array.Copy(Sorted, 0, BD, BoxStart*30, Sorted.Length); + Array.Copy(Sorted, 0, BD, BoxStart*BoxSlotCount, Sorted.Length); BoxData = BD; } public void resetBoxes(int BoxStart = 0, int BoxEnd = -1) @@ -437,13 +439,13 @@ public void resetBoxes(int BoxStart = 0, int BoxEnd = -1) for (int i = BoxStart; i < BoxEnd; i++) { int offset = getBoxOffset(i); - for (int p = 0; p < 30; p++) + for (int p = 0; p < BoxSlotCount; p++) setStoredSlot(BlankPKM, offset + SIZE_STORED * p); } } public byte[] getPCBin() { return BoxData.SelectMany(pk => pk.EncryptedBoxData).ToArray(); } - public byte[] getBoxBin(int box) { return BoxData.Skip(box*30).Take(30).SelectMany(pk => pk.EncryptedBoxData).ToArray(); } + public byte[] getBoxBin(int box) { return BoxData.Skip(box*BoxSlotCount).Take(BoxSlotCount).SelectMany(pk => pk.EncryptedBoxData).ToArray(); } public bool setPCBin(byte[] data) { if (data.Length != getPCBin().Length) @@ -476,8 +478,8 @@ public bool setBoxBin(byte[] data, int box) } PKM[] pkms = BoxData; - for (int i = 0; i < 30; i++) - pkms[box*30 + i].Data = decryptPKM(pkdata[i]); + for (int i = 0; i < BoxSlotCount; i++) + pkms[box*BoxSlotCount + i].Data = decryptPKM(pkdata[i]); BoxData = pkms; return true; } diff --git a/PKHeX/Saves/SaveUtil.cs b/PKHeX/Saves/SaveUtil.cs index f10c94de9..8c53069c5 100644 --- a/PKHeX/Saves/SaveUtil.cs +++ b/PKHeX/Saves/SaveUtil.cs @@ -212,6 +212,8 @@ public static SaveFile getVariantSAV(byte[] data) { switch (getSAVGeneration(data)) { + case 1: + return new SAV1(data); case 3: return new SAV3(data); case 4: From 8cfe57d504c41331b1855c0a6abb9c3853b40916 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 28 Aug 2016 22:21:55 -0700 Subject: [PATCH 07/16] Implement PK1 loading/editing/saving. --- PKHeX/MainWindow/Main.cs | 45 +++++++++++++++++++++++++++++-------- PKHeX/MainWindow/MainPK1.cs | 2 +- PKHeX/PKM/PK1.cs | 40 ++++++++++++++++++++++++--------- PKHeX/PKM/PKM.cs | 2 +- PKHeX/PKM/PKMConverter.cs | 20 +++++++++++++++++ PKHeX/PKM/PKX.cs | 3 ++- PKHeX/Saves/SAV1.cs | 2 +- PKHeX/Saves/SaveFile.cs | 2 ++ 8 files changed, 93 insertions(+), 23 deletions(-) diff --git a/PKHeX/MainWindow/Main.cs b/PKHeX/MainWindow/Main.cs index 1adc20910..3af0b7051 100644 --- a/PKHeX/MainWindow/Main.cs +++ b/PKHeX/MainWindow/Main.cs @@ -237,7 +237,7 @@ private void mainMenuSave(object sender, EventArgs e) SaveFileDialog sfd = new SaveFileDialog { Filter = $"Decrypted PKM File|*.{pkx}" + - $"|Encrypted PKM File|*.{ekx}" + + (SAV.Generation > 2 ? "" : $"|Encrypted PKM File|*.{ekx}") + "|Binary File|*.bin" + "|All Files|*.*", DefaultExt = pkx, @@ -592,6 +592,8 @@ private void openFile(byte[] input, string path, string ext) PKM pk = PKMConverter.convertToFormat(temp, SAV.Generation, out c); if (pk == null) Util.Alert("Conversion failed.", c); + else if (SAV.Generation == 1 && ((PK1) pk).Japanese != SAV.GetJapanese) + Util.Alert(string.Format("Cannot load {0} PK1 in {1} save file.", SAV.GetJapanese ? "an International" : "a Japanese", SAV.GetJapanese ? "a Japanese" : "an International")); else populateFields(pk); Console.WriteLine(c); @@ -848,7 +850,23 @@ private void loadSAV(SaveFile sav, string path) Label_CharacteristicPrefix.Visible = L_Characteristic.Visible = SAV.Generation > 1; Label_ContestStats.Visible = Label_Cool.Visible = Label_Tough.Visible = Label_Smart.Visible = Label_Sheen.Visible = Label_Beauty.Visible = Label_Cute.Visible = TB_Cool.Visible = TB_Tough.Visible = - TB_Smart.Visible = TB_Sheen.Visible = TB_Beauty.Visible = TB_Cute.Visible = SAV.Generation >= 3; + TB_Smart.Visible = TB_Sheen.Visible = TB_Beauty.Visible = TB_Cute.Visible = Label_Nature.Visible = + CB_Nature.Visible = Label_Language.Visible = CB_Language.Visible = Label_Ability.Visible = + Label_Friendship.Visible = Label_HatchCounter.Visible = TB_Friendship.Visible = BTN_RerollPID.Visible = + Label_PID.Visible = TB_PID.Visible = Label_SID.Visible = TB_SID.Visible = SAV.Generation >= 3; + + // Met Tab + CHK_Fateful.Visible = Label_OriginGame.Visible = Label_Ball.Visible = Label_MetLevel.Visible = + Label_MetLocation.Visible = CB_GameOrigin.Visible = CB_Ball.Visible = CB_MetLocation.Visible = + TB_MetLevel.Visible = SAV.Generation > 2; + + CHK_Infected.Visible = CHK_Cured.Visible = SAV.Generation >= 3; + + CHK_IsEgg.Visible = Label_Gender.Visible = SAV.Generation > 1; + + Label_OTGender.Visible = SAV.Generation > 1; + + CHK_Nicknamed.Enabled = SAV.Generation > 2; if (1 <= sav.Generation && sav.Generation <= 2) { @@ -922,7 +940,7 @@ private void loadSAV(SaveFile sav, string path) bool init = fieldsInitialized; fieldsInitialized = false; populateFilteredDataSources(); - populateFields(pkm.Format != SAV.Generation ? SAV.BlankPKM : pk); + populateFields((pkm.Format != SAV.Generation || SAV.Generation == 1) ? SAV.BlankPKM : pk); fieldsInitialized |= init; // SAV Specific Limits @@ -1312,8 +1330,8 @@ private void setIsShiny(object sender) bool isShiny = pkm.IsShiny; // Set the Controls - BTN_Shinytize.Visible = BTN_Shinytize.Enabled = !isShiny; - Label_IsShiny.Visible = isShiny; + BTN_Shinytize.Visible = BTN_Shinytize.Enabled = !isShiny && SAV.Generation > 2; + Label_IsShiny.Visible = isShiny && SAV.Generation > 1; // Refresh Markings (for Shiny Star if applicable) setMarkings(); @@ -1686,6 +1704,7 @@ private void updateRandomIVs(object sender, EventArgs e) } private void updateRandomEVs(object sender, EventArgs e) { + changingFields = true; if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift) { // Max EVs @@ -1706,6 +1725,8 @@ private void updateRandomEVs(object sender, EventArgs e) TB_SPDEV.Text = evs[4].ToString(); TB_SPEEV.Text = evs[5].ToString(); } + changingFields = false; + updateEVs(null, null); } private void updateRandomPID(object sender, EventArgs e) { @@ -2174,8 +2195,9 @@ private void updateIsEgg(object sender, EventArgs e) } } // Display hatch counter if it is an egg, Display Friendship if it is not. - Label_HatchCounter.Visible = CHK_IsEgg.Checked; - Label_Friendship.Visible = !CHK_IsEgg.Checked; + Label_HatchCounter.Visible = CHK_IsEgg.Checked && SAV.Generation > 1; + Label_Friendship.Visible = !CHK_IsEgg.Checked && SAV.Generation > 2; + // Update image to (not) show egg. if (!fieldsInitialized) return; @@ -2981,11 +3003,13 @@ public void setPKXBoxes() for (int i = 0; i < 30; i++) { if (i < SAV.BoxSlotCount) - getSlotFiller(boxoffset + SAV.SIZE_STORED*i, SlotPictureBoxes[i]); + { + getSlotFiller(boxoffset + SAV.SIZE_STORED * i, SlotPictureBoxes[i]); + } else { SlotPictureBoxes[i].Image = null; - SlotPictureBoxes[i].BackColor = Color.Gray; + SlotPictureBoxes[i].Visible = false; } } } @@ -3100,6 +3124,7 @@ private void getSlotFiller(int offset, PictureBox pb) // 00s present in slot. pb.Image = null; pb.BackColor = Color.Transparent; + pb.Visible = true; return; } PKM p = SAV.getStoredSlot(offset); @@ -3108,11 +3133,13 @@ private void getSlotFiller(int offset, PictureBox pb) // Bad Egg present in slot. pb.Image = null; pb.BackColor = Color.Red; + pb.Visible = true; return; } // Something stored in slot. Only display if species is valid. pb.Image = p.Species == 0 ? null : p.Sprite; pb.BackColor = Color.Transparent; + pb.Visible = true; } private void getSlotColor(int slot, Image color) { diff --git a/PKHeX/MainWindow/MainPK1.cs b/PKHeX/MainWindow/MainPK1.cs index f34be25cf..401bff69f 100644 --- a/PKHeX/MainWindow/MainPK1.cs +++ b/PKHeX/MainWindow/MainPK1.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace PKHeX { @@ -94,7 +95,6 @@ private PKM preparePK1() pk1.IV_SPE = Util.ToInt32(TB_SPEIV.Text); pk1.IV_SPA = Util.ToInt32(TB_SPAIV.Text); - pk1.OT_Name = TB_OT.Text; // Toss in Party Stats diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index 64f7307b6..cebcf5208 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -8,8 +8,8 @@ namespace PKHeX class PK1 : PKM { // Internal use only - protected byte[] otname; - protected byte[] nick; + protected internal byte[] otname; + protected internal byte[] nick; public byte[] OT_Name_Raw => (byte[])otname.Clone(); public byte[] Nickname_Raw => (byte[])nick.Clone(); @@ -24,6 +24,8 @@ class PK1 : PKM public bool Japanese => otname.Length == STRLEN_J; + public override string FileName => $"{Species.ToString("000")} - {Nickname} - {OT_Name}.{Extension}"; + public PK1(byte[] decryptedData = null, string ident = null, bool jp = false) { Data = (byte[])(decryptedData ?? new byte[SIZE_PARTY]).Clone(); @@ -41,7 +43,7 @@ public PK1(byte[] decryptedData = null, string ident = null, bool jp = false) public override PKM Clone() { - PK1 new_pk1 = new PK1(Data); + PK1 new_pk1 = new PK1(Data, Identifier, Japanese); Array.Copy(otname, 0, new_pk1.otname, 0, otname.Length); Array.Copy(nick, 0, new_pk1.nick, 0, nick.Length); return new_pk1; @@ -53,7 +55,15 @@ public override string Nickname { byte[] strdata = PKX.setG1Str(value, Japanese); if (strdata.Length > StringLength) - throw new ArgumentOutOfRangeException("OT Name too long for given PK1"); + throw new ArgumentOutOfRangeException($"Nickname {value} too long for given PK1"); + if (nick.Any(b => b == 0) && nick[StringLength - 1] == 0x50 && Array.FindIndex(nick, b => b == 0) == strdata.Length - 1) // Handle JP Mew event with grace + { + int firstInd = Array.FindIndex(nick, b => b == 0); + for (int i = firstInd; i < StringLength - 1; i++) + if (nick[i] != 0) + break; + strdata = strdata.Take(strdata.Length - 1).ToArray(); + } strdata.CopyTo(nick, 0); } } @@ -65,7 +75,15 @@ public override string OT_Name { byte[] strdata = PKX.setG1Str(value, Japanese); if (strdata.Length > StringLength) - throw new ArgumentOutOfRangeException("OT Name too long for given PK1"); + throw new ArgumentOutOfRangeException($"OT Name {value} too long for given PK1"); + if (otname.Any(b => b == 0) && otname[StringLength - 1] == 0x50 && Array.FindIndex(otname, b => b == 0) == strdata.Length - 1) // Handle JP Mew event with grace + { + int firstInd = Array.FindIndex(otname, b => b == 0); + for (int i = firstInd; i < StringLength - 1; i++) + if (otname[i] != 0) + break; + strdata = strdata.Take(strdata.Length - 1).ToArray(); + } strdata.CopyTo(otname, 0); } } @@ -80,6 +98,8 @@ public override byte[] Encrypt() // Please forgive me. public override byte[] EncryptedPartyData => Encrypt().ToArray(); public override byte[] EncryptedBoxData => Encrypt().ToArray(); + public override byte[] DecryptedBoxData => Encrypt().ToArray(); + public override byte[] DecryptedPartyData => Encrypt().ToArray(); public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } @@ -119,7 +139,7 @@ public override uint EXP public override int EV_SPE { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x17)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x17); } } public int EV_SPC { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x19)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x19); } } public override int EV_SPA { get { return EV_SPC; } set { EV_SPC = value; } } - public override int EV_SPD { get { return EV_SPC; } set { EV_SPC = value; } } + public override int EV_SPD { get { return EV_SPC; } set { } } public ushort DV16 { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x1B)); } set { BitConverter.GetBytes(Util.SwapEndianness(value)).CopyTo(Data, 0x1B); } } public override int IV_HP { get { return ((IV_ATK & 1) << 3) | ((IV_DEF & 1) << 2) | ((IV_SPE & 1) << 1) | ((IV_SPC & 1) << 0); } set { } } public override int IV_ATK { get { return (DV16 >> 12) & 0xF; } set { DV16 = (ushort)((DV16 & ~(0xF << 12)) | (ushort)((value > 0xF ? 0xF : value) << 12)); } } @@ -151,7 +171,7 @@ public override int Stat_Level public int Stat_SPC { get { return Util.SwapEndianness(BitConverter.ToUInt16(Data, 0x2A)); } set { BitConverter.GetBytes(Util.SwapEndianness((ushort)value)).CopyTo(Data, 0x2A); } } // Leave SPA and SPD as alias for SPC public override int Stat_SPA { get { return Stat_SPC; } set { Stat_SPC = value; } } - public override int Stat_SPD { get { return Stat_SPC; } set { Stat_SPC = value; } } + public override int Stat_SPD { get { return Stat_SPC; } set { } } #endregion public override ushort[] getStats(PersonalInfo p) @@ -278,8 +298,8 @@ public PokemonList1(byte[] d, CapacityType c = CapacityType.Single, bool jp = fa int base_ofs = 2 + Capacity; byte[] dat = Data.Skip(base_ofs + Entry_Size * i).Take(Entry_Size).ToArray(); Pokemon[i] = new PK1(dat, null, jp); - Pokemon[i].OT_Name = PKX.getG1Str(Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * i).Take(StringLength).ToArray(), Japanese); - Pokemon[i].Nickname = PKX.getG1Str(Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * Capacity + StringLength * i).Take(StringLength).ToArray(), Japanese); + Pokemon[i].otname = Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * i).Take(StringLength).ToArray(); + Pokemon[i].nick = Data.Skip(base_ofs + Capacity * Entry_Size + StringLength * Capacity + StringLength * i).Take(StringLength).ToArray(); } } @@ -331,7 +351,7 @@ private void Update() { for (int i = 0; i < Count; i++) { - Data[1 + i] = (byte)Pokemon[i].Species; + Data[1 + i] = (byte)PKX.setG1Species(Pokemon[i].Species); Array.Copy(Pokemon[i].Data, 0, Data, 2 + Capacity + Entry_Size * i, Entry_Size); Array.Copy(Pokemon[i].OT_Name_Raw, 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * i, StringLength); Array.Copy(Pokemon[i].Nickname_Raw, 0, Data, 2 + Capacity + Capacity * Entry_Size + StringLength * Capacity + StringLength * i, StringLength); diff --git a/PKHeX/PKM/PKM.cs b/PKHeX/PKM/PKM.cs index 517e36570..84b89785f 100644 --- a/PKHeX/PKM/PKM.cs +++ b/PKHeX/PKM/PKM.cs @@ -261,7 +261,7 @@ public int GenNumber public Image Sprite => PKX.getSprite(this); public string ShowdownText => ShowdownSet.getShowdownText(this); public string[] QRText => PKX.getQRText(this); - public string FileName => $"{Species.ToString("000")}{(IsShiny ? " ★" : "")} - {Nickname} - {Checksum.ToString("X4")}{EncryptionConstant.ToString("X8")}.{Extension}"; + public virtual string FileName => $"{Species.ToString("000")}{(IsShiny ? " ★" : "")} - {Nickname} - {Checksum.ToString("X4")}{EncryptionConstant.ToString("X8")}.{Extension}"; public int[] IVs { get { return new[] { IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD }; } diff --git a/PKHeX/PKM/PKMConverter.cs b/PKHeX/PKM/PKMConverter.cs index be573542a..6637c6579 100644 --- a/PKHeX/PKM/PKMConverter.cs +++ b/PKHeX/PKM/PKMConverter.cs @@ -31,6 +31,9 @@ public static int getPKMDataFormat(byte[] data) switch (data.Length) { + case PKX.SIZE_1JLIST: + case PKX.SIZE_1ULIST: + return 1; case PKX.SIZE_3PARTY: case PKX.SIZE_3STORED: return 3; @@ -70,6 +73,11 @@ public static PKM getPKMfromBytes(byte[] data, string ident = null) checkEncrypted(ref data); switch (getPKMDataFormat(data)) { + case 1: + var PL = new PokemonList1(data, PokemonList1.CapacityType.Single, data.Length == PKX.SIZE_1JLIST); + if (ident != null) + PL[0].Identifier = ident; + return PL[0]; case 3: return new PK3(data, ident); case 4: @@ -101,6 +109,17 @@ internal static PKM convertToFormat(PKM pk, int Format, out string comment) + "Desired Format: " + Format; return null; } + if ((pk.Format == 1 || pk.Format == 2) && 2 < Format && Format < 7) + { + comment = $"Cannot convert a PK{pk.Format} to a PK{Format}."; + return null; + } + if (pk.Format == 1 && Format == 7) + { + comment = "PK1 to PK7 conversion is not yet supported." + Environment.NewLine + + "Please wait for Sun/Moon to release and documentation to occur."; + return null; + } string currentFormat = pk.Format.ToString(); PKM pkm = pk.Clone(); if (pkm.IsEgg) // force hatch @@ -130,6 +149,7 @@ internal static void checkEncrypted(ref byte[] pkm) ushort chk = 0; switch (format) { + case 1: case 3: // TOneverDO, nobody exports encrypted pk3s return; case 4: diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index ee24587f5..c2c5d6066 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -38,7 +38,7 @@ public static class PKX /// A boolean indicating whether or not the length is valid for a Pokemon file. public static bool getIsPKM(long len) { - return new[] {SIZE_3STORED, SIZE_3PARTY, SIZE_4STORED, SIZE_4PARTY, SIZE_5PARTY, SIZE_6STORED, SIZE_6PARTY}.Contains((int)len); + return new[] {SIZE_1JLIST, SIZE_1ULIST, SIZE_3STORED, SIZE_3PARTY, SIZE_4STORED, SIZE_4PARTY, SIZE_5PARTY, SIZE_6STORED, SIZE_6PARTY}.Contains((int)len); } // C# PKX Function Library @@ -1852,6 +1852,7 @@ public static ushort getG4Item(ushort g3val) {"ぷ", 0x46}, {"ぺ", 0x47}, {"ぽ", 0x48}, + {"\0", 0x50}, {"トレーナー", 0x5D}, {"ア", 0x80}, {"イ", 0x81}, diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index bc98a5600..386bffb98 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -105,7 +105,7 @@ public override byte[] Write(bool DSV) // Configuration - public override SaveFile Clone() { return new SAV1(Data); } + public override SaveFile Clone() { return new SAV1(Data.Take(Data.Length - SIZE_RESERVED).ToArray()); } public override int SIZE_STORED => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; public override int SIZE_PARTY => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs index fdc5c86d5..f171242a3 100644 --- a/PKHeX/Saves/SaveFile.cs +++ b/PKHeX/Saves/SaveFile.cs @@ -21,6 +21,8 @@ public abstract class SaveFile public byte[] Footer { protected get; set; } = new byte[0]; // .dsv public bool Japanese { protected get; set; } + public bool GetJapanese => Japanese; + // General PKM Properties protected abstract Type PKMType { get; } public abstract PKM getPKM(byte[] data); From b94f3c8918eb808b497d58e3ee5956610e33f265 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 29 Aug 2016 13:27:17 -0700 Subject: [PATCH 08/16] Implement SAV1 exporting. --- PKHeX/MainWindow/Main.Designer.cs | 1 + PKHeX/MainWindow/Main.cs | 30 ++++++++++++++- PKHeX/MainWindow/MainPK1.cs | 3 ++ PKHeX/PKM/PK1.cs | 26 ++++++++++++- PKHeX/PKM/PKX.cs | 19 +++++++--- PKHeX/Saves/SAV1.cs | 62 +++++++++++++++++++++++++++---- PKHeX/Saves/SaveFile.cs | 2 +- 7 files changed, 126 insertions(+), 17 deletions(-) diff --git a/PKHeX/MainWindow/Main.Designer.cs b/PKHeX/MainWindow/Main.Designer.cs index dbc698903..14db5ba68 100644 --- a/PKHeX/MainWindow/Main.Designer.cs +++ b/PKHeX/MainWindow/Main.Designer.cs @@ -926,6 +926,7 @@ public void InitializeComponent() this.TB_Nickname.Name = "TB_Nickname"; this.TB_Nickname.Size = new System.Drawing.Size(122, 20); this.TB_Nickname.TabIndex = 5; + this.TB_Nickname.TextChanged += new System.EventHandler(this.updateIsNicknamed); this.TB_Nickname.MouseDown += new System.Windows.Forms.MouseEventHandler(this.updateNicknameClick); // // CB_Species diff --git a/PKHeX/MainWindow/Main.cs b/PKHeX/MainWindow/Main.cs index 3af0b7051..33c389038 100644 --- a/PKHeX/MainWindow/Main.cs +++ b/PKHeX/MainWindow/Main.cs @@ -862,12 +862,13 @@ private void loadSAV(SaveFile sav, string path) CHK_Infected.Visible = CHK_Cured.Visible = SAV.Generation >= 3; + // Second daycare slot + SlotPictureBoxes[43].Visible = SAV.Generation > 1; + CHK_IsEgg.Visible = Label_Gender.Visible = SAV.Generation > 1; Label_OTGender.Visible = SAV.Generation > 1; - CHK_Nicknamed.Enabled = SAV.Generation > 2; - if (1 <= sav.Generation && sav.Generation <= 2) { Label_SPD.Visible = TB_SPDEV.Visible = TB_SPDIV.Visible = Stat_SPD.Visible = false; @@ -2141,6 +2142,8 @@ private void updateNickname(object sender, EventArgs e) if (SAV.Generation < 5) // All caps GenIV and previous nick = nick.ToUpper(); TB_Nickname.Text = nick; + if (SAV.Generation == 1) + ((PK1)pkm).setNotNicknamed(); } } private void updateNicknameClick(object sender, MouseEventArgs e) @@ -2943,6 +2946,28 @@ private void updateU64(object sender, EventArgs e) SAV.Edited = true; } } + + private void updateIsNicknamed(object sender, EventArgs e) + { + if (!CHK_Nicknamed.Checked) + { + int species = Util.getIndex(CB_Species); + if (species < 1 || species > SAV.MaxSpeciesID) + return; + int lang = Util.getIndex(CB_Language); + if (CHK_IsEgg.Checked) species = 0; // Set species to 0 to get the egg name. + string nick = PKX.getSpeciesName(CHK_IsEgg.Checked ? 0 : species, lang); + + if (SAV.Generation < 5) // All caps GenIV and previous + nick = nick.ToUpper(); + if (TB_Nickname.Text != nick) + { + CHK_Nicknamed.Checked = true; + pkm.Nickname = TB_Nickname.Text; + } + } + } + // Generic Subfunctions // private void setParty() { @@ -3155,6 +3180,7 @@ private void getSlotColor(int slot, Image color) } private void getBox(object sender, EventArgs e) { + SAV.CurrentBox = CB_BoxSelect.SelectedIndex; setPKXBoxes(); } private void switchDaycare(object sender, EventArgs e) diff --git a/PKHeX/MainWindow/MainPK1.cs b/PKHeX/MainWindow/MainPK1.cs index 401bff69f..06d755fe1 100644 --- a/PKHeX/MainWindow/MainPK1.cs +++ b/PKHeX/MainWindow/MainPK1.cs @@ -22,6 +22,7 @@ private void populateFieldsPK1() // Load rest TB_TID.Text = pk1.TID.ToString("00000"); + CHK_Nicknamed.Checked = pk1.IsNicknamed; TB_Nickname.Text = pk1.Nickname; TB_OT.Text = pk1.OT_Name; GB_OT.BackgroundImage = null; @@ -55,6 +56,8 @@ private void populateFieldsPK1() TB_PP3.Text = pk1.Move3_PP.ToString(); TB_PP4.Text = pk1.Move4_PP.ToString(); + CB_Language.SelectedIndex = pk1.Japanese ? 0 : 1; + updateStats(); TB_EXP.Text = pk1.EXP.ToString(); diff --git a/PKHeX/PKM/PK1.cs b/PKHeX/PKM/PK1.cs index cebcf5208..de49fd3f9 100644 --- a/PKHeX/PKM/PK1.cs +++ b/PKHeX/PKM/PK1.cs @@ -101,7 +101,25 @@ public override byte[] Encrypt() public override byte[] DecryptedBoxData => Encrypt().ToArray(); public override byte[] DecryptedPartyData => Encrypt().ToArray(); - public override bool IsNicknamed { get { throw new NotImplementedException(); } set { } } + public override bool IsNicknamed + { + get + { + string spName = PKX.getSpeciesName(Species, Japanese ? 1 : 2).ToUpper(); + return + !nick.SequenceEqual( + PKX.setG1Str(spName, Japanese) + .Concat(Enumerable.Repeat((byte) 0x50, StringLength - spName.Length - 1))); + } + set { } + } + + public void setNotNicknamed() + { + string spName = PKX.getSpeciesName(Species, Japanese ? 1 : 2).ToUpper(); + nick = PKX.setG1Str(spName, Japanese).Concat(Enumerable.Repeat((byte)0x50, StringLength - spName.Length - 1)).ToArray(); + } + #region Stored Attributes public override int Species @@ -343,12 +361,16 @@ public int GetCapacity() set { if (value == null) return; - Pokemon[i] = (PK1)value.Clone(); + Pokemon[i] = (PK1)(((PK1)value).Clone()); } } private void Update() { + if (Pokemon.Any(pk => (pk.Species == 0))) + Count = (byte) Array.FindIndex(Pokemon, pk => (pk.Species == 0)); + else + Count = Capacity; for (int i = 0; i < Count; i++) { Data[1 + i] = (byte)PKX.setG1Species(Pokemon[i].Species); diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index c2c5d6066..53facdc21 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -1841,6 +1841,7 @@ public static ushort getG4Item(ushort g3val) {"ば", 0x3A}, {"び", 0x3B}, {"ぶ", 0x3C}, + {"ベ", 0x3D}, {"べ", 0x3D}, {"ぼ", 0x3E}, {"パ", 0x40}, @@ -1851,13 +1852,16 @@ public static ushort getG4Item(ushort g3val) {"ぴ", 0x45}, {"ぷ", 0x46}, {"ぺ", 0x47}, + {"ペ", 0x47}, {"ぽ", 0x48}, {"\0", 0x50}, {"トレーナー", 0x5D}, {"ア", 0x80}, {"イ", 0x81}, {"ウ", 0x82}, + {"ェ", 0x83}, {"エ", 0x83}, + {"オ", 0x84}, {"ォ", 0x84}, {"カ", 0x85}, {"キ", 0x86}, @@ -1942,6 +1946,7 @@ public static ushort getG4Item(ushort g3val) {"ゆ", 0xD5}, {"よ", 0xD6}, {"ら", 0xD7}, + {"リ", 0xD8}, {"り", 0xD8}, {"る", 0xD9}, {"れ", 0xDA}, @@ -1955,6 +1960,8 @@ public static ushort getG4Item(ushort g3val) {"ょ", 0xE2}, {"ー", 0xE3}, {"ァ", 0xE9}, + {"♂", 0xEF}, + {"♀", 0xF5} }; static Dictionary RBY2U_J => new Dictionary { @@ -1995,7 +2002,7 @@ public static ushort getG4Item(ushort g3val) {0x3A, "ば"}, {0x3B, "び"}, {0x3C, "ぶ"}, - {0x3D, "べ"}, + {0x3D, "ベ"}, {0x3E, "ぼ"}, {0x40, "パ"}, {0x41, "ピ"}, @@ -2004,15 +2011,15 @@ public static ushort getG4Item(ushort g3val) {0x44, "ぱ"}, {0x45, "ぴ"}, {0x46, "ぷ"}, - {0x47, "ぺ"}, + {0x47, "ペ"}, {0x48, "ぽ"}, {0x50, "\0"}, {0x5D, "トレーナー"}, {0x80, "ア"}, {0x81, "イ"}, {0x82, "ウ"}, - {0x83, "エ"}, - {0x84, "ォ"}, + {0x83, "ェ"}, + {0x84, "オ"}, {0x85, "カ"}, {0x86, "キ"}, {0x87, "ク"}, @@ -2096,7 +2103,7 @@ public static ushort getG4Item(ushort g3val) {0xD5, "ゆ"}, {0xD6, "よ"}, {0xD7, "ら"}, - {0xD8, "り"}, + {0xD8, "リ"}, {0xD9, "る"}, {0xDA, "れ"}, {0xDB, "ろ"}, @@ -2109,6 +2116,8 @@ public static ushort getG4Item(ushort g3val) {0xE2, "ょ"}, {0xE3, "ー"}, {0xE9, "ァ"}, + {0xEF, "♂"}, + {0xF5, "♀"} }; #endregion diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index 386bffb98..76c13180d 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -31,7 +31,7 @@ public SAV1(byte[] data = null) Personal = PersonalTable.RBY; // Stash boxes after the save file's end. - byte[] TempBox = new byte[SIZE_BOX]; + byte[] TempBox = new byte[SIZE_STOREDBOX]; for (int i = 0; i < BoxCount; i++) { if (i < BoxCount / 2) @@ -87,8 +87,16 @@ public SAV1(byte[] data = null) } } - File.WriteAllBytes("temp.sav", Data); - + byte[] rawDC = new byte[0x38]; + Array.Copy(Data, Japanese ? 0x2CA7 : 0x2CF4, rawDC, 0, rawDC.Length); + byte[] TempDaycare = new byte[PokemonList1.GetDataLength(PokemonList1.CapacityType.Single, Japanese)]; + TempDaycare[0] = rawDC[0]; + Array.Copy(rawDC, 1, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY + StringLength, StringLength); + Array.Copy(rawDC, 1 + StringLength, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY, StringLength); + Array.Copy(rawDC, 1 + 2 * StringLength, TempDaycare, 2 + 1, PKX.SIZE_1STORED); + PokemonList1 daycareList = new PokemonList1(TempDaycare, PokemonList1.CapacityType.Single, Japanese); + daycareList.GetBytes().CopyTo(Data, getPartyOffset(7)); + Daycare = getPartyOffset(7); if (!Exportable) resetBoxes(); @@ -97,10 +105,47 @@ public SAV1(byte[] data = null) private const int SIZE_RESERVED = 0x8000; // unpacked box data public override byte[] Write(bool DSV) { - // TODO: Implement Box Data Relocation + for (int i = 0; i < BoxCount; i++) + { + PokemonList1 boxPL = new PokemonList1(Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + int slot = 0; + for (int j = 0; j < boxPL.Pokemon.Length; j++) + { + PK1 boxPK = (PK1) getPKM(getData(getBoxOffset(i) + j*SIZE_STORED, SIZE_STORED)); + if (boxPK.Species > 0) + boxPL[slot++] = boxPK; + } + if (i < BoxCount / 2) + boxPL.GetBytes().CopyTo(Data, 0x4000 + i * SIZE_STOREDBOX); + else + boxPL.GetBytes().CopyTo(Data, 0x6000 + (i - BoxCount / 2) * SIZE_STOREDBOX); + if (i == CurrentBox) + boxPL.GetBytes().CopyTo(Data, Japanese ? 0x302D : 0x30C0); + } + + PokemonList1 partyPL = new PokemonList1(PokemonList1.CapacityType.Party, Japanese); + int pSlot = 0; + for (int i = 0; i < 6; i++) + { + PK1 partyPK = (PK1)getPKM(getData(getPartyOffset(i), SIZE_STORED)); + if (partyPK.Species > 0) + partyPL[pSlot++] = partyPK; + } + partyPL.GetBytes().CopyTo(Data, Japanese ? 0x2ED5 : 0x2F2C); + + // Daycare is read-only, but in case it ever becomes editable, copy it back in. + byte[] rawDC = getData(getDaycareSlotOffset(0, 0), SIZE_STORED); + byte[] dc = new byte[1 + 2*StringLength + PKX.SIZE_1STORED]; + dc[0] = rawDC[0]; + Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY + StringLength, dc, 1, StringLength); + Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY, dc, 1 + StringLength, StringLength); + Array.Copy(rawDC, 2 + 1, dc, 1 + 2*StringLength, PKX.SIZE_1STORED); + dc.CopyTo(Data, Japanese ? 0x2CA7 : 0x2CF4); + setChecksums(); - Array.Resize(ref Data, Data.Length - SIZE_RESERVED); - return Data; + byte[] outData = new byte[Data.Length - SIZE_RESERVED]; + Array.Copy(Data, outData, outData.Length); + return outData; } @@ -110,7 +155,10 @@ public override byte[] Write(bool DSV) public override int SIZE_STORED => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; public override int SIZE_PARTY => Japanese ? PKX.SIZE_1JLIST : PKX.SIZE_1ULIST; - public int SIZE_BOX => PokemonList1.GetDataLength(Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + public int SIZE_BOX => BoxSlotCount*SIZE_STORED; + + public int SIZE_STOREDBOX => PokemonList1.GetDataLength(Japanese ? PokemonList1.CapacityType.StoredJP : PokemonList1.CapacityType.Stored, Japanese); + public override PKM BlankPKM => new PK1(null, null, Japanese); protected override Type PKMType => typeof(PK1); diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs index f171242a3..5ff237205 100644 --- a/PKHeX/Saves/SaveFile.cs +++ b/PKHeX/Saves/SaveFile.cs @@ -361,7 +361,7 @@ public void setPartySlot(PKM pkm, int offset, bool? trade = null, bool? dex = nu Console.WriteLine(""); Edited = true; } - public void setStoredSlot(PKM pkm, int offset, bool? trade = null, bool? dex = null) + public virtual void setStoredSlot(PKM pkm, int offset, bool? trade = null, bool? dex = null) { if (pkm == null) return; if (pkm.GetType() != PKMType) From b91324fb2eecdf4c9baf66999b05fbd2fb749abb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 29 Aug 2016 17:48:05 -0700 Subject: [PATCH 09/16] Trainer Info/Pokedex editing for Gen I --- PKHeX/MainWindow/Main.cs | 2 + PKHeX/PKHeX.csproj | 10 + PKHeX/Saves/SAV1.cs | 121 +++++++++- PKHeX/Saves/SaveFile.cs | 11 +- .../SAV_SimplePokedex.Designer.cs | 179 +++++++++++++++ .../Save Editors/SAV_SimplePokedex.cs | 93 ++++++++ .../Save Editors/SAV_SimplePokedex.resx | 216 ++++++++++++++++++ .../SAV_SimpleTrainer.Designer.cs | 145 +++++++++++- .../Save Editors/SAV_SimpleTrainer.cs | 41 +++- .../Save Editors/SAV_SimpleTrainer.resx | 96 ++++++++ 10 files changed, 902 insertions(+), 12 deletions(-) create mode 100644 PKHeX/Subforms/Save Editors/SAV_SimplePokedex.Designer.cs create mode 100644 PKHeX/Subforms/Save Editors/SAV_SimplePokedex.cs create mode 100644 PKHeX/Subforms/Save Editors/SAV_SimplePokedex.resx diff --git a/PKHeX/MainWindow/Main.cs b/PKHeX/MainWindow/Main.cs index 33c389038..a2739c7b0 100644 --- a/PKHeX/MainWindow/Main.cs +++ b/PKHeX/MainWindow/Main.cs @@ -3366,6 +3366,8 @@ private void B_OpenPokedex_Click(object sender, EventArgs e) new SAV_PokedexORAS().ShowDialog(); else if (SAV.XY) new SAV_PokedexXY().ShowDialog(); + else if (SAV.RBY) + new SAV_SimplePokedex().ShowDialog(); } private void B_OUTPasserby_Click(object sender, EventArgs e) { diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index 21ee6cfea..00903517d 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -201,6 +201,12 @@ SAV_BoxViewer.cs + + Form + + + SAV_SimplePokedex.cs + Form @@ -354,6 +360,9 @@ SAV_BoxViewer.cs + + SAV_SimplePokedex.cs + SAV_Database.cs @@ -412,6 +421,7 @@ Designer + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index 76c13180d..e94815e49 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -98,6 +98,9 @@ public SAV1(byte[] data = null) daycareList.GetBytes().CopyTo(Data, getPartyOffset(7)); Daycare = getPartyOffset(7); + // Enable Pokedex editing + PokeDex = 0; + if (!Exportable) resetBoxes(); } @@ -134,7 +137,7 @@ public override byte[] Write(bool DSV) partyPL.GetBytes().CopyTo(Data, Japanese ? 0x2ED5 : 0x2F2C); // Daycare is read-only, but in case it ever becomes editable, copy it back in. - byte[] rawDC = getData(getDaycareSlotOffset(0, 0), SIZE_STORED); + byte[] rawDC = getData(getDaycareSlotOffset(), SIZE_STORED); byte[] dc = new byte[1 + 2*StringLength + PKX.SIZE_1STORED]; dc[0] = rawDC[0]; Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY + StringLength, dc, 1, StringLength); @@ -268,6 +271,58 @@ public override int PlayedSeconds set { Data[Japanese ? 0x2CA3 : 0x2CF0] = (byte)value; } } + public int Badges + { + get { return Data[Japanese ? 0x25F8 : 0x2602]; } + set { if (value < 0) return; Data[Japanese ? 0x25F8 : 0x2602] = (byte)value; } + } + + private byte Options + { + get { return Data[Japanese ? 0x25F7 : 0x2601]; } + set { Data[Japanese ? 0x25F7 : 0x2601] = value; } + } + + public bool BattleEffects + { + get { return (Options & 0x80) == 0; } + set { Options = (byte)((Options & 0x7F) | (value ? 0 : 0x80)); } + } + + public bool BattleStyleSwitch + { + get { return (Options & 0x40) == 0; } + set { Options = (byte)((Options & 0xBF) | (value ? 0 : 0x40)); } + } + + public int Sound + { + get { return (Options & 0x30) >> 4; } + set + { + var new_sound = value; + if (new_sound > 3) + new_sound = 3; + if (new_sound < 0) + new_sound = 0; + Options = (byte)((Options & 0xCF) | (new_sound << 4)); + } + } + + public int TextSpeed + { + get { return Options & 0x7; } + set + { + var new_speed = value; + if (new_speed > 7) + new_speed = 7; + if (new_speed < 0) + new_speed = 0; + Options = (byte)((Options & 0xF8) | new_speed); + } + } + public override uint Money { get { return uint.Parse((Util.SwapEndianness(BitConverter.ToUInt32(Data, Japanese ? 0x25EE : 0x25F3)) >> 8).ToString("X6")); } @@ -396,7 +451,39 @@ public override byte[] decryptPKM(byte[] data) return data; } - protected override void setDex(PKM pkm) + public override bool getSeen(PKM pkm) + { + if (pkm.Species == 0) + return false; + if (pkm.Species > MaxSpeciesID) + return false; + if (Version == GameVersion.Unknown) + return false; + + int bit = pkm.Species - 1; + int ofs = bit >> 3; + byte bitval = (byte)(1 << (bit & 7)); + // Get the Seen Flag + return (Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] & bitval) != 0; + } + + public override bool getCaught(PKM pkm) + { + if (pkm.Species == 0) + return false; + if (pkm.Species > MaxSpeciesID) + return false; + if (Version == GameVersion.Unknown) + return false; + + int bit = pkm.Species - 1; + int ofs = bit >> 3; + byte bitval = (byte)(1 << (bit & 7)); + // Get the Caught Flag + return (Data[(Japanese ? 0x259E : 0x25A3) + ofs] & bitval) != 0; + } + + protected internal override void setSeen(PKM pkm, bool seen) { if (pkm.Species == 0) return; @@ -404,16 +491,32 @@ protected override void setDex(PKM pkm) return; if (Version == GameVersion.Unknown) return; - + int bit = pkm.Species - 1; int ofs = bit >> 3; - byte bitval = (byte)(1 << (bit % 7)); - - // Set the Captured Flag - Data[(Japanese ? 0x259E : 0x25A3) + ofs] |= bitval; - + byte bitval = (byte)(1 << (bit & 7)); // Set the Seen Flag - Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] |= bitval; + Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] &= (byte)(~bitval); + if (seen) + Data[(Japanese ? 0x25B1 : 0x25B6) + ofs] |= bitval; + } + + protected internal override void setCaught(PKM pkm, bool caught) + { + if (pkm.Species == 0) + return; + if (pkm.Species > MaxSpeciesID) + return; + if (Version == GameVersion.Unknown) + return; + + int bit = pkm.Species - 1; + int ofs = bit >> 3; + byte bitval = (byte)(1 << (bit & 7)); + // Set the Captured Flag + Data[(Japanese ? 0x259E : 0x25A3) + ofs] &= (byte)(~bitval); + if (caught) + Data[(Japanese ? 0x259E : 0x25A3) + ofs] |= bitval; } } } diff --git a/PKHeX/Saves/SaveFile.cs b/PKHeX/Saves/SaveFile.cs index 5ff237205..1d672eb03 100644 --- a/PKHeX/Saves/SaveFile.cs +++ b/PKHeX/Saves/SaveFile.cs @@ -487,7 +487,16 @@ public bool setBoxBin(byte[] data, int box) } protected virtual void setPKM(PKM pkm) { } - protected virtual void setDex(PKM pkm) { } + protected virtual void setDex(PKM pkm) + { + setSeen(pkm); + setCaught(pkm); + } + + public virtual bool getSeen(PKM pkm) { throw new NotImplementedException(); } + public virtual bool getCaught(PKM pkm) { throw new NotImplementedException(); } + protected internal virtual void setSeen(PKM pkm, bool seen = true) { } + protected internal virtual void setCaught(PKM pkm, bool caught = true) { } public byte[] getData(int Offset, int Length) { diff --git a/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.Designer.cs b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.Designer.cs new file mode 100644 index 000000000..cf25e0653 --- /dev/null +++ b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.Designer.cs @@ -0,0 +1,179 @@ +namespace PKHeX +{ + partial class SAV_SimplePokedex + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SAV_SimplePokedex)); + this.B_Save = new System.Windows.Forms.Button(); + this.B_Cancel = new System.Windows.Forms.Button(); + this.B_CaughtNone = new System.Windows.Forms.Button(); + this.B_CaughtAll = new System.Windows.Forms.Button(); + this.B_SeenNone = new System.Windows.Forms.Button(); + this.B_SeenAll = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.CLB_Caught = new System.Windows.Forms.CheckedListBox(); + this.Label_Seen = new System.Windows.Forms.Label(); + this.CLB_Seen = new System.Windows.Forms.CheckedListBox(); + this.SuspendLayout(); + // + // B_Save + // + this.B_Save.Location = new System.Drawing.Point(146, 301); + this.B_Save.Name = "B_Save"; + this.B_Save.Size = new System.Drawing.Size(85, 23); + this.B_Save.TabIndex = 19; + this.B_Save.Text = "Save"; + this.B_Save.UseVisualStyleBackColor = true; + this.B_Save.Click += new System.EventHandler(this.B_Save_Click); + // + // B_Cancel + // + this.B_Cancel.Location = new System.Drawing.Point(53, 301); + this.B_Cancel.Name = "B_Cancel"; + this.B_Cancel.Size = new System.Drawing.Size(85, 23); + this.B_Cancel.TabIndex = 18; + this.B_Cancel.Text = "Cancel"; + this.B_Cancel.UseVisualStyleBackColor = true; + this.B_Cancel.Click += new System.EventHandler(this.B_Cancel_Click); + // + // B_CaughtNone + // + this.B_CaughtNone.Location = new System.Drawing.Point(151, 267); + this.B_CaughtNone.Name = "B_CaughtNone"; + this.B_CaughtNone.Size = new System.Drawing.Size(120, 23); + this.B_CaughtNone.TabIndex = 17; + this.B_CaughtNone.Text = "Caught None"; + this.B_CaughtNone.UseVisualStyleBackColor = true; + this.B_CaughtNone.Click += new System.EventHandler(this.B_CaughtNone_Click); + // + // B_CaughtAll + // + this.B_CaughtAll.Location = new System.Drawing.Point(151, 238); + this.B_CaughtAll.Name = "B_CaughtAll"; + this.B_CaughtAll.Size = new System.Drawing.Size(120, 23); + this.B_CaughtAll.TabIndex = 16; + this.B_CaughtAll.Text = "Caught All"; + this.B_CaughtAll.UseVisualStyleBackColor = true; + this.B_CaughtAll.Click += new System.EventHandler(this.B_CaughtAll_Click); + // + // B_SeenNone + // + this.B_SeenNone.Location = new System.Drawing.Point(14, 267); + this.B_SeenNone.Name = "B_SeenNone"; + this.B_SeenNone.Size = new System.Drawing.Size(120, 23); + this.B_SeenNone.TabIndex = 15; + this.B_SeenNone.Text = "Seen None"; + this.B_SeenNone.UseVisualStyleBackColor = true; + this.B_SeenNone.Click += new System.EventHandler(this.B_SeenNone_Click); + // + // B_SeenAll + // + this.B_SeenAll.Location = new System.Drawing.Point(14, 238); + this.B_SeenAll.Name = "B_SeenAll"; + this.B_SeenAll.Size = new System.Drawing.Size(120, 23); + this.B_SeenAll.TabIndex = 14; + this.B_SeenAll.Text = "Seen All"; + this.B_SeenAll.UseVisualStyleBackColor = true; + this.B_SeenAll.Click += new System.EventHandler(this.B_SeenAll_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(151, 13); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(44, 13); + this.label2.TabIndex = 13; + this.label2.Text = "Caught:"; + // + // CLB_Caught + // + this.CLB_Caught.FormattingEnabled = true; + this.CLB_Caught.Location = new System.Drawing.Point(151, 33); + this.CLB_Caught.Name = "CLB_Caught"; + this.CLB_Caught.Size = new System.Drawing.Size(120, 199); + this.CLB_Caught.TabIndex = 12; + this.CLB_Caught.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.CLB_Caught_ItemCheck); + // + // Label_Seen + // + this.Label_Seen.AutoSize = true; + this.Label_Seen.Location = new System.Drawing.Point(14, 13); + this.Label_Seen.Name = "Label_Seen"; + this.Label_Seen.Size = new System.Drawing.Size(35, 13); + this.Label_Seen.TabIndex = 11; + this.Label_Seen.Text = "Seen:"; + // + // CLB_Seen + // + this.CLB_Seen.FormattingEnabled = true; + this.CLB_Seen.Location = new System.Drawing.Point(14, 33); + this.CLB_Seen.Name = "CLB_Seen"; + this.CLB_Seen.Size = new System.Drawing.Size(120, 199); + this.CLB_Seen.TabIndex = 10; + this.CLB_Seen.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.CLB_Seen_ItemCheck); + // + // SAV_SimplePokedex + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 336); + this.Controls.Add(this.B_Save); + this.Controls.Add(this.B_Cancel); + this.Controls.Add(this.B_CaughtNone); + this.Controls.Add(this.B_CaughtAll); + this.Controls.Add(this.B_SeenNone); + this.Controls.Add(this.B_SeenAll); + this.Controls.Add(this.label2); + this.Controls.Add(this.CLB_Caught); + this.Controls.Add(this.Label_Seen); + this.Controls.Add(this.CLB_Seen); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximumSize = new System.Drawing.Size(300, 375); + this.MinimumSize = new System.Drawing.Size(300, 375); + this.Name = "SAV_SimplePokedex"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Pokedex Editor"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.Button B_Cancel; + private System.Windows.Forms.Button B_CaughtNone; + private System.Windows.Forms.Button B_CaughtAll; + private System.Windows.Forms.Button B_SeenNone; + private System.Windows.Forms.Button B_SeenAll; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckedListBox CLB_Caught; + private System.Windows.Forms.Label Label_Seen; + private System.Windows.Forms.CheckedListBox CLB_Seen; + } +} \ No newline at end of file diff --git a/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.cs b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.cs new file mode 100644 index 000000000..7821be892 --- /dev/null +++ b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.cs @@ -0,0 +1,93 @@ +using System; +using System.Linq; +using System.Windows.Forms; +using System.Windows.Forms.VisualStyles; + +namespace PKHeX +{ + public partial class SAV_SimplePokedex : Form + { + public SAV_SimplePokedex() + { + InitializeComponent(); + Util.TranslateInterface(this, Main.curlanguage); + seen = new bool[SAV.MaxSpeciesID]; + caught = new bool[SAV.MaxSpeciesID]; + + string[] spec = Util.getSpeciesList(Main.curlanguage); + for (int i = 0; i < seen.Length; i++) + { + PKM tempPkm = new PK6(); + tempPkm.Species = i + 1; + seen[i] = SAV.getSeen(tempPkm); + caught[i] = SAV.getCaught(tempPkm); + CLB_Seen.Items.Add(spec[i + 1]); + CLB_Caught.Items.Add(spec[i + 1]); + CLB_Seen.SetItemChecked(i, seen[i]); + CLB_Caught.SetItemChecked(i, caught[i]); + } + initialized = true; + } + private readonly CheckBox[] cba; + private readonly SaveFile SAV = Main.SAV.Clone(); + + private bool[] seen; + private bool[] caught; + private bool initialized; + + private void B_Save_Click(object sender, EventArgs e) + { + for (int i = 0; i < seen.Length; i++) + { + PKM tempPkm = new PK6(); + tempPkm.Species = i + 1; + SAV.setSeen(tempPkm, seen[i]); + SAV.setCaught(tempPkm, caught[i]); + } + SAV.Data.CopyTo(Main.SAV.Data, 0); + Main.SAV.Edited = true; + Close(); + } + + private void B_Cancel_Click(object sender, EventArgs e) + { + Close(); + } + + private void B_SeenAll_Click(object sender, EventArgs e) + { + for (int i = 0; i < SAV.MaxSpeciesID; i++) + CLB_Seen.SetItemChecked(i, true); + } + + private void B_SeenNone_Click(object sender, EventArgs e) + { + for (int i = 0; i < SAV.MaxSpeciesID; i++) + CLB_Seen.SetItemChecked(i, false); + } + + private void B_CaughtAll_Click(object sender, EventArgs e) + { + for (int i = 0; i < SAV.MaxSpeciesID; i++) + CLB_Caught.SetItemChecked(i, true); + } + + private void B_CaughtNone_Click(object sender, EventArgs e) + { + for (int i = 0; i < SAV.MaxSpeciesID; i++) + CLB_Caught.SetItemChecked(i, false); + } + + private void CLB_Seen_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (!initialized) return; + seen[e.Index] = e.NewValue == CheckState.Checked; + } + + private void CLB_Caught_ItemCheck(object sender, ItemCheckEventArgs e) + { + if (!initialized) return; + caught[e.Index] = e.NewValue == CheckState.Checked; + } + } +} diff --git a/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.resx b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.resx new file mode 100644 index 000000000..603f660be --- /dev/null +++ b/PKHeX/Subforms/Save Editors/SAV_SimplePokedex.resx @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAE + AAAAAAAAAAAAAAAAAAAAAAAAIyMjAQAAAAALCwsPJiYmJysrKycqKionKSkpJykpKScpKSknKioqJyoq + KicrKysnJycnJw0ODQ8AAAAAJiYmAQAAAABpaWlHq6ur17+/v+6+vr7svr6+7b6+vu2+vr7tvr6+7b6+ + vu2+vr7tvr6+7L+/v+6rq6vXampqSAAAAAAoKSgXvr++3eLi4v/g4OD94eHh/+Hh4f/i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Dh4P/g4OD94uLi/7+/v90sLCwXfn5+PNna2frg4OD/39/f/uHh4f7h4eH+39/f/uDg + 4P7g4OD+39/f/uHh4f7h4OH+39/f/t/g3//a2tr6g4ODPoOCgz7X19f64+Pj/+Li4v7k5OT/4+Tj//Ly + 8v/19fX/9PT0//T09P/k5OT/5OTk/+Pj4/7j4+P/19jX+4qLikCDhIM+2tra++Xl5f/k5eT+5OTk//Lz + 8v+urq7/RUVF/z4+Pv+Zmpn/8fHx/+Xm5f/k5eT+5eXl/9ra2vyLi4tAhYWFPuXm5vvx8vP/7+/w/v// + //+sra3/AgIC/15eXv9tbG3/BQUF/4yMjP//////7+/w/vHy8//l5ub8jY2NQC4uLD5LS0f7UFBL/09P + Sv5YWVP/FBUS/29wcP///////////5SUlP8PDw//U1NO/1BQS/5PT0r/S0tH/DIyMEAAAAs+AAAM+wAA + Dv8AAA/+AwMS/wAAAP+UlJX///////////+3t7n/AAAA/wAAD/8BAQ/+AAAO/wAADPwCAg5ABARSPgoK + k/sNDab/DQ2o/hAQvP8CAmj/IiIW/7Kzrv/Cw8D/NDQm/wAATf8QELz/DQ2q/gwMp/8LC5T8Dg5bQAUF + Xj4KCpz7DQ2u/w0NsP4NDbX/Dw+//wUFYf8CAhL/AwMP/wMDTf8ODrj/Dg64/w0NsP4MDK7/Cwud/A8P + aEEGBmU9DAyl+w4Otf8ODrf+Dw+6/xAQvv8TE8v/EhK+/xAQvP8TE8v/EBDA/w8Puf8PD7f+Dg61/w0N + pvsREW9ACAhtQA8PsfsTE77/ExO//xQUwP8UFML/FBTD/xUVyP8WFsn/FRXE/xQUw/8UFMH/ExO//xMT + vv8QELL7ERF3QxkZdCgXF771ExPH/xUVyPwVFcn9FhbL/RcXzP0XF8z9FxfM/RcXy/0XF8v9FhbJ/RUV + yPwTE8f/Fxe+9RkZdykAAAAAIyOtghsbx/8ZGcj+GRnJ/xoayf8aGsn/GhrK/xoayv8aGsn/GhrJ/xkZ + yf8ZGcj+GxvH/yMjrYQAAAAAAADHAQAAAAAzM51FLCyscCoqrGwqKqxtKSmsbSoqrG0qKqxtKSmsbSoq + rG0qKqxsLCyscDMznUUAAAAAAAAAAP//AADAAwAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAIABAACAAQAAgAEAAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKysrCR0dHSMWFhY3GBgYORgYGDkYGBg5GBgYORgY + GDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5FxcXNx4e + HiQuLi4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASEhIARYWFis7OzuVkJCQ2ampqeqqqqrsqqqq7Kqq + quyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqq + quypqanqkZGR2j09PZcXFxcsUFBQAQAAAAAAAAAAAAAAAAAAAAASEhIuhISEytvb2/7W1tb/19fX/9jY + 2P/Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/9nZ2f/Y2Nj/2NjY/9jY + 2P/Y2Nj/2NjY/9fX1//W1tb/29vb/oeHh8sTExMvAAAAAAAAAAAAAAAAPDw8DGtra6zZ2dn/2dnZ/9ra + 2v/b29v/29vb/9vb2//c3Nz/3Nzc/9zc3P/c3Nz/3d3d/93d3f/d3d3/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/c3Nz/3Nzc/9vb2//b29v/29vb/9ra2v/Z2dn/2dnZ/21tba5DQ0MNAAAAAAAAAAAiIiIx1NXU9tna + 2f/c3Nz/3d3d/93e3f/e3t7/3t7e/9/f3//f39//39/f/9/g3//g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg + 4P/g4OD/39/f/9/f3//f39//3t/e/97e3v/d3t3/3d3d/9zc3P/Z2tn/1dXV9icnJzMAAAAAAAAAAFhZ + WFzf4N//3Nzc/97e3v/f39//39/f/9/g3//g4OD/4ODg/+Hh4f/h4eH/4eHh/+Li4v/i4uL/4uLi/+Li + 4v/i4uL/4uLi/+Hi4f/h4eH/4eHh/+Dg4P/g4OD/3+Df/9/f3//f39//3t7e/9zc3P/f39//XV1dXQAA + AAAAAAAAZmZmZdvc2//e3t7/3+Df/+Dg4P/g4eD/4eHh/+Hi4f/i4uL/4uPi/+Pj4//j4+P/5OTk/+Tk + 5P/k5OT/5OTk/+Tk5P/k5OT/4+Pj/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/f4N//3t7e/9vb + 2/9wcHBoAAAAAAAAAABoaGhl3d3d/9/f3//h4eH/4eLh/+Li4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl + 5f/l5uX/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/f39//3N3c/3Nzc2kAAAAAAAAAAGhoaGXe3t7/4ODg/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm + 5v/m5+b/5+fn/+fn5//n6Of/6Ojo/+jo6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pk + 4//j4+P/4uLi/+Dg4P/e3t7/c3NzaQAAAAAAAAAAaGhoZd/g3//i4uL/5OTk/+Tl5P/l5eX/5ebl/+bn + 5v/n5+f/5+jn/+jp6P/p6en/7Ozs/8LCwv+Tk5P/ioqK/66urv/o6ej/6enp/+jp6P/o6Oj/5+jn/+bn + 5v/m5ub/5ebl/+Tl5P/k5OT/4uLi/9/g3/9zdHNpAAAAAAAAAABoaWhl4eLh/+Pk4//m5ub/5ubm/+fn + 5//n6Of/6Ojo/+np6f/p6un/6urq/8bGxv8yMjL/AAAA/wAAAP8AAAD/AAAA/xMTE/+ZmZn/7Ozs/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/k5OT/4eHh/3R0dGkAAAAAAAAAAGhpaGXj4+P/5eXl/+fn + 5//n6Of/6Ojo/+np6f/q6ur/6urq/+vr6//Dw8P/DAwM/wAAAP8AAAD/Gxsb/ygoKP8BAQH/AAAA/wAA + AP+FhYX/7O3s/+rr6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+Xl5f/i4+L/dHR0aQAAAAAAAAAAYWFhZeTl + 5P/m5+b/6Ono/+np6f/p6un/6uvq/+vr6//s7Oz/7e7t/ycnJ/8AAAD/Ghoa/7S0tP/m5ub/5OTk/9HR + 0f9GRkb/AAAA/wICAv/IyMj/7Ozs/+vs6//q6+r/6urq/+nq6f/o6ej/5+fn/+Tk5P9sbGxpAAAAAAAA + AAA9Pj1lj4+P/5OTk/+VlZX/lpaW/5eXl/+YmJj/mZmZ/5qamv92dnb/AAAA/wEBAf+/wL//3Nzc/+Tk + 5P/l5eX/3d3d/+Li4v8mJib/AAAA/0ZGRv+ampr/mZmZ/5iYmP+Xl5f/lpaW/5WVlf+Tk5P/j4+P/0ZG + RmoAAAAAAAAAAAwMDGUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Nzc3/+fn + 5//q6ur/7O3s/+zt7P/v7+//39/f/4WFhf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8AAAD/EBAQagAAAAAAAAAAAwMHZQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP9NTU3/5ufm//Lz8v/z9PP/8/Tz//X19f/l5eX/nZ2d/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP8GBgpqAAAAAAAAAAAAABZlAQEk/wEBJ/8CAin/AgIq/wICKv8CAiv/AgIs/wIC + LP8BAR3/AAAA/xwcHP/w8PD/6+zr//r6+v/6+vr/9PT0/+vr6/9lZWX/AAAA/wAAD/8CAi3/AgIs/wIC + K/8CAir/AgIq/wICKf8BASf/AQEl/wUFG2oAAAAAAAAAAAICQGUGBpL/Bwec/wgIo/8JCaf/CQmq/wkJ + rf8JCa//Cgqz/wkJqP8AAAL/AAAA/4CAgP/y8/L/6+zr/+3t7f/u7u7/xMTE/wcHB/8AAAD/BgZz/woK + s/8JCbD/CQmt/wkJqv8JCaj/CAik/wcHnf8HB5P/Dg5MagAAAAAAAAAAAwNHZQgIk/8JCZ3/Cgqj/wsL + p/8LC6n/Cwus/wsLr/8MDLL/DAy2/wYGW/8AAAD/AAAA/1JSUv+sraz/tra2/3h4eP8KCgr/AAAA/wIC + Iv8MDLb/DAyy/wsLsP8LC63/Cwuq/wsLp/8KCqT/CQmd/wgIk/8PD1VrAAAAAAAAAAAEBE1lCQmY/woK + ov8LC6j/DAyr/wwMrf8MDLD/DAyy/w0Ntf8NDbf/Dg67/wUFSv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8CAiH/DQ2q/w0NuP8NDbX/DQ2z/wwMsP8MDK7/DAyr/wsLqP8KCqL/CQmZ/xAQWmsAAAAAAAAAAAQE + UGUKCp7/Cwum/wwMrP8NDa//DQ2w/w0Ns/8ODrX/Dg63/w4Ouf8ODrv/Dw/A/wwMiv8FBTj/AAAG/wAA + AP8DAyb/CQls/w8Pu/8PD7z/Dg66/w4OuP8ODrX/DQ2z/w0Nsf8NDa//DAys/wsLp/8KCp7/ERFeawAA + AAAAAAAABQVTZQsLpP8MDKv/DQ2w/w4Os/8ODrT/Dg62/w8PuP8PD7r/Dw+8/w8Pvf8QEL//EBDA/xER + w/8SEsn/ERHJ/xERxf8QEMD/EBC//w8Pvv8PD7z/Dw+6/w8PuP8ODrf/Dg61/w4Os/8NDbH/DAyr/wsL + pP8SEmFrAAAAAAAAAAAGBlZlDAyq/w4OsP8PD7X/Dw+3/w8PuP8QELr/EBC7/xAQvf8REb7/ERHA/xER + wf8REcL/EhLC/xISw/8SEsP/EhLC/xERwv8REcH/ERHA/xERvv8QEL3/EBC7/xAQuv8QELj/Dw+3/w8P + tf8ODrD/DAyq/xMTZWsAAAAAAAAAAAcHWmUODrD/EBC2/xERuv8REbz/ERG9/xISvv8SEr//EhLA/xMT + wf8TE8P/ExPD/xMTxP8TE8X/FBTF/xQUxf8UFMX/ExPE/xMTxP8TE8P/ExPC/xISwf8SEr//EhK+/xER + vf8REbz/ERG6/xAQtv8ODrD/FBRpawAAAAAAAAAACAhcYxAQtf8SErv/ExO+/xQUwP8UFMD/FBTB/xUV + wv8VFcP/FRXE/xUVxf8WFsb/FhbG/xYWx/8WFsf/FhbH/xYWx/8WFsf/FhbG/xYWxf8VFcT/FRXD/xUV + wv8UFMH/FBTB/xQUwP8TE77/EhK7/xAQtf8TE2hoAAAAAAAAAAAQEFNUFRXC/xMTv/8UFMP/FRXE/xUV + xP8VFcX/FRXG/xYWx/8WFsf/FhbI/xYWyf8XF8n/FxfK/xcXyv8XF8r/FxfK/xcXyf8XF8n/FhbI/xYW + yP8WFsf/FhbG/xUVxf8VFcT/FRXE/xQUw/8TE7//FRXB/xAQV1UAAAAAAAAAAA0NPxkjI8byFBTD/xUV + x/8WFsj/FxfJ/xcXyf8XF8r/FxfK/xcXy/8YGMz/GBjM/xgYzP8YGM3/GBjN/xgYzf8YGM3/GBjM/xgY + zP8YGMz/GBjL/xcXy/8XF8r/FxfJ/xcXyf8WFsj/FRXH/xQUw/8jI8f0Dg5GGwAAAAAAAAAAFhZxAiUl + eIUZGcr/FBTI/xUVyv8WFsv/FhbM/xYWzP8WFsz/FhbN/xcXzf8XF83/FxfN/xcXzv8XF87/FxfO/xcX + zv8XF87/FxfN/xcXzf8WFs3/FhbM/xYWzP8WFsz/FhbL/xUVyv8UFMj/GBjJ/yYmeogWFnYCAAAAAAAA + AAAAAAAAGBh1BzMzk50kJNP+FxfK/xgYzP8YGMz/GBjN/xgYzf8YGM3/GBjN/xgYzf8ZGc7/GRnO/xkZ + zv8ZGc7/GRnO/xkZzv8YGM3/GBjN/xgYzf8YGM3/GBjN/xgYzP8YGMz/FxfK/yMj0v4zM5WfFBRkBwAA + AAAAAAAAAAAAAAAAAAAAAAAAHBx7Ay0tdkg3N5emMTGpxSwsp8gsLKfILCynyCwsp8gsLKfILCynyCws + p8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyDExqcU2NpenLi54Shsb + ewMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////8AAAD+AAAAfAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAAD4AAAB/gAAB////// + + + \ No newline at end of file diff --git a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.Designer.cs b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.Designer.cs index 111a04802..9cdf8aca3 100644 --- a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.Designer.cs +++ b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.Designer.cs @@ -28,6 +28,7 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SAV_SimpleTrainer)); this.GB_Adventure = new System.Windows.Forms.GroupBox(); this.L_Started = new System.Windows.Forms.Label(); this.CAL_AdventureStartDate = new System.Windows.Forms.DateTimePicker(); @@ -63,6 +64,9 @@ private void InitializeComponent() this.B_Save = new System.Windows.Forms.Button(); this.B_Cancel = new System.Windows.Forms.Button(); this.GB_Trainer = new System.Windows.Forms.GroupBox(); + this.B_MaxCoins = new System.Windows.Forms.Button(); + this.L_Coins = new System.Windows.Forms.Label(); + this.MT_Coins = new System.Windows.Forms.MaskedTextBox(); this.GB_Badges = new System.Windows.Forms.GroupBox(); this.CHK_H8 = new System.Windows.Forms.CheckBox(); this.CHK_H7 = new System.Windows.Forms.CheckBox(); @@ -80,6 +84,14 @@ private void InitializeComponent() this.CHK_3 = new System.Windows.Forms.CheckBox(); this.CHK_2 = new System.Windows.Forms.CheckBox(); this.CHK_1 = new System.Windows.Forms.CheckBox(); + this.GB_Options = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.CB_SoundType = new System.Windows.Forms.ComboBox(); + this.LBL_TextSpeed = new System.Windows.Forms.Label(); + this.CB_TextSpeed = new System.Windows.Forms.ComboBox(); + this.LBL_BattleStyle = new System.Windows.Forms.Label(); + this.CB_BattleStyle = new System.Windows.Forms.ComboBox(); + this.CHK_BattleEffects = new System.Windows.Forms.CheckBox(); this.GB_Adventure.SuspendLayout(); this.GB_Map.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.NUD_Z)).BeginInit(); @@ -88,6 +100,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.NUD_X)).BeginInit(); this.GB_Trainer.SuspendLayout(); this.GB_Badges.SuspendLayout(); + this.GB_Options.SuspendLayout(); this.SuspendLayout(); // // GB_Adventure @@ -248,7 +261,7 @@ private void InitializeComponent() this.CB_Gender.Items.AddRange(new object[] { "♂", "♀"}); - this.CB_Gender.Location = new System.Drawing.Point(99, 55); + this.CB_Gender.Location = new System.Drawing.Point(119, 55); this.CB_Gender.Name = "CB_Gender"; this.CB_Gender.Size = new System.Drawing.Size(40, 21); this.CB_Gender.TabIndex = 68; @@ -458,6 +471,9 @@ private void InitializeComponent() // // GB_Trainer // + this.GB_Trainer.Controls.Add(this.B_MaxCoins); + this.GB_Trainer.Controls.Add(this.L_Coins); + this.GB_Trainer.Controls.Add(this.MT_Coins); this.GB_Trainer.Controls.Add(this.TB_OTName); this.GB_Trainer.Controls.Add(this.B_MaxCash); this.GB_Trainer.Controls.Add(this.MT_SID); @@ -475,6 +491,37 @@ private void InitializeComponent() this.GB_Trainer.TabStop = false; this.GB_Trainer.Text = "Trainer"; // + // B_MaxCoins + // + this.B_MaxCoins.Location = new System.Drawing.Point(95, 56); + this.B_MaxCoins.Name = "B_MaxCoins"; + this.B_MaxCoins.Size = new System.Drawing.Size(20, 20); + this.B_MaxCoins.TabIndex = 71; + this.B_MaxCoins.Text = "+"; + this.B_MaxCoins.UseVisualStyleBackColor = true; + this.B_MaxCoins.Visible = false; + // + // L_Coins + // + this.L_Coins.AutoSize = true; + this.L_Coins.Location = new System.Drawing.Point(11, 59); + this.L_Coins.Name = "L_Coins"; + this.L_Coins.Size = new System.Drawing.Size(36, 13); + this.L_Coins.TabIndex = 70; + this.L_Coins.Text = "Coins:"; + this.L_Coins.Visible = false; + // + // MT_Coins + // + this.MT_Coins.Location = new System.Drawing.Point(53, 55); + this.MT_Coins.Mask = "00000"; + this.MT_Coins.Name = "MT_Coins"; + this.MT_Coins.RightToLeft = System.Windows.Forms.RightToLeft.Yes; + this.MT_Coins.Size = new System.Drawing.Size(39, 20); + this.MT_Coins.TabIndex = 69; + this.MT_Coins.TextAlign = System.Windows.Forms.HorizontalAlignment.Center; + this.MT_Coins.Visible = false; + // // GB_Badges // this.GB_Badges.Controls.Add(this.CHK_H8); @@ -660,17 +707,100 @@ private void InitializeComponent() this.CHK_1.UseVisualStyleBackColor = true; this.CHK_1.Visible = false; // + // GB_Options + // + this.GB_Options.Controls.Add(this.label1); + this.GB_Options.Controls.Add(this.CB_SoundType); + this.GB_Options.Controls.Add(this.LBL_TextSpeed); + this.GB_Options.Controls.Add(this.CB_TextSpeed); + this.GB_Options.Controls.Add(this.LBL_BattleStyle); + this.GB_Options.Controls.Add(this.CB_BattleStyle); + this.GB_Options.Controls.Add(this.CHK_BattleEffects); + this.GB_Options.Location = new System.Drawing.Point(217, 99); + this.GB_Options.Name = "GB_Options"; + this.GB_Options.Size = new System.Drawing.Size(157, 125); + this.GB_Options.TabIndex = 72; + this.GB_Options.TabStop = false; + this.GB_Options.Text = "Options"; + this.GB_Options.Visible = false; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(3, 71); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(68, 13); + this.label1.TabIndex = 25; + this.label1.Text = "Sound Type:"; + // + // CB_SoundType + // + this.CB_SoundType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_SoundType.FormattingEnabled = true; + this.CB_SoundType.Location = new System.Drawing.Point(71, 68); + this.CB_SoundType.Name = "CB_SoundType"; + this.CB_SoundType.Size = new System.Drawing.Size(80, 21); + this.CB_SoundType.TabIndex = 24; + // + // LBL_TextSpeed + // + this.LBL_TextSpeed.AutoSize = true; + this.LBL_TextSpeed.Location = new System.Drawing.Point(6, 98); + this.LBL_TextSpeed.Name = "LBL_TextSpeed"; + this.LBL_TextSpeed.Size = new System.Drawing.Size(65, 13); + this.LBL_TextSpeed.TabIndex = 23; + this.LBL_TextSpeed.Text = "Text Speed:"; + // + // CB_TextSpeed + // + this.CB_TextSpeed.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_TextSpeed.FormattingEnabled = true; + this.CB_TextSpeed.Location = new System.Drawing.Point(71, 95); + this.CB_TextSpeed.Name = "CB_TextSpeed"; + this.CB_TextSpeed.Size = new System.Drawing.Size(80, 21); + this.CB_TextSpeed.TabIndex = 22; + // + // LBL_BattleStyle + // + this.LBL_BattleStyle.AutoSize = true; + this.LBL_BattleStyle.Location = new System.Drawing.Point(8, 44); + this.LBL_BattleStyle.Name = "LBL_BattleStyle"; + this.LBL_BattleStyle.Size = new System.Drawing.Size(63, 13); + this.LBL_BattleStyle.TabIndex = 21; + this.LBL_BattleStyle.Text = "Battle Style:"; + // + // CB_BattleStyle + // + this.CB_BattleStyle.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.CB_BattleStyle.FormattingEnabled = true; + this.CB_BattleStyle.Location = new System.Drawing.Point(71, 41); + this.CB_BattleStyle.Name = "CB_BattleStyle"; + this.CB_BattleStyle.Size = new System.Drawing.Size(80, 21); + this.CB_BattleStyle.TabIndex = 20; + // + // CHK_BattleEffects + // + this.CHK_BattleEffects.AutoSize = true; + this.CHK_BattleEffects.Location = new System.Drawing.Point(26, 18); + this.CHK_BattleEffects.Name = "CHK_BattleEffects"; + this.CHK_BattleEffects.Size = new System.Drawing.Size(111, 17); + this.CHK_BattleEffects.TabIndex = 19; + this.CHK_BattleEffects.Text = "Use Battle Effects"; + this.CHK_BattleEffects.UseVisualStyleBackColor = true; + // // SAV_SimpleTrainer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(384, 261); + this.Controls.Add(this.GB_Options); this.Controls.Add(this.GB_Badges); this.Controls.Add(this.GB_Trainer); this.Controls.Add(this.B_Save); this.Controls.Add(this.B_Cancel); this.Controls.Add(this.GB_Map); this.Controls.Add(this.GB_Adventure); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MinimumSize = new System.Drawing.Size(400, 300); this.Name = "SAV_SimpleTrainer"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; @@ -686,6 +816,8 @@ private void InitializeComponent() this.GB_Trainer.PerformLayout(); this.GB_Badges.ResumeLayout(false); this.GB_Badges.PerformLayout(); + this.GB_Options.ResumeLayout(false); + this.GB_Options.PerformLayout(); this.ResumeLayout(false); } @@ -744,5 +876,16 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox CHK_H3; private System.Windows.Forms.CheckBox CHK_H2; private System.Windows.Forms.CheckBox CHK_H1; + private System.Windows.Forms.Button B_MaxCoins; + private System.Windows.Forms.Label L_Coins; + private System.Windows.Forms.MaskedTextBox MT_Coins; + private System.Windows.Forms.GroupBox GB_Options; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox CB_SoundType; + private System.Windows.Forms.Label LBL_TextSpeed; + private System.Windows.Forms.ComboBox CB_TextSpeed; + private System.Windows.Forms.Label LBL_BattleStyle; + private System.Windows.Forms.ComboBox CB_BattleStyle; + private System.Windows.Forms.CheckBox CHK_BattleEffects; } } \ No newline at end of file diff --git a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.cs b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.cs index cd77cf21f..ea487cb4c 100644 --- a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.cs +++ b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.cs @@ -14,10 +14,15 @@ public SAV_SimpleTrainer() cba = new[] {CHK_1, CHK_2, CHK_3, CHK_4, CHK_5, CHK_6, CHK_7, CHK_8}; TB_OTName.MaxLength = SAV.OTLength; B_MaxCash.Click += (sender, e) => MT_Money.Text = "9,999,999"; + B_MaxCoins.Click += (sender, e) => MT_Coins.Text = "9999"; CB_Gender.Items.Clear(); CB_Gender.Items.AddRange(Main.gendersymbols.Take(2).ToArray()); // m/f depending on unicode selection + L_SID.Visible = MT_SID.Visible = SAV.Generation > 2; + L_Coins.Visible = B_MaxCoins.Visible = MT_Coins.Visible = SAV.Generation < 3; + CB_Gender.Visible = SAV.Generation > 1; + TB_OTName.Text = SAV.OT; CB_Gender.SelectedIndex = SAV.Gender; MT_TID.Text = SAV.TID.ToString("00000"); @@ -27,6 +32,29 @@ public SAV_SimpleTrainer() MT_Minutes.Text = SAV.PlayedMinutes.ToString(); MT_Seconds.Text = SAV.PlayedSeconds.ToString(); + + int badgeval = 0; + if (SAV is SAV1) + { + SAV1 sav1 = (SAV1)SAV; + MT_Coins.Text = sav1.Coin.ToString(); + badgeval = sav1.Badges; + + L_Started.Visible = L_Fame.Visible = false; + CAL_AdventureStartDate.Visible = CAL_HoFDate.Visible = false; + CAL_AdventureStartTime.Visible = CAL_HoFTime.Visible = false; + GB_Map.Visible = false; + GB_Options.Visible = true; + CB_BattleStyle.Items.AddRange(new[] { "Switch", "Set" }); + CB_SoundType.Items.AddRange(new[] { "Mono", "Stereo", "Earphone2", "Earphone3" }); + CB_TextSpeed.Items.AddRange(new[] { "0 (Instant)", "1 (Fast)", "2", "3 (Normal)", "4", "5 (Slow)", "6", "7" }); + + CHK_BattleEffects.Checked = sav1.BattleEffects; + CB_BattleStyle.SelectedIndex = sav1.BattleStyleSwitch ? 0 : 1; + CB_SoundType.SelectedIndex = sav1.Sound; + CB_TextSpeed.SelectedIndex = sav1.TextSpeed; + } + if (SAV is SAV3) { GB_Map.Visible = false; @@ -38,7 +66,6 @@ public SAV_SimpleTrainer() return; } - int badgeval = 0; if (SAV is SAV4) { SAV4 s = (SAV4)SAV; @@ -104,6 +131,18 @@ private void B_Save_Click(object sender, EventArgs e) for (int i = 0; i < cba.Length; i++) badgeval |= (cba[i].Checked ? 1 : 0) << i; + if (SAV is SAV1) + { + SAV1 sav1 = (SAV1) SAV; + sav1.Coin = (ushort) Util.ToUInt32(MT_Coins.Text); + sav1.Badges = badgeval & 0xFF; + + sav1.BattleEffects = CHK_BattleEffects.Checked; + sav1.BattleStyleSwitch = CB_BattleStyle.SelectedIndex == 0; + sav1.Sound = CB_SoundType.SelectedIndex; + sav1.TextSpeed = CB_TextSpeed.SelectedIndex; + } + if (SAV is SAV4) { SAV4 s = (SAV4)SAV; diff --git a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.resx b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.resx index 1af7de150..603f660be 100644 --- a/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.resx +++ b/PKHeX/Subforms/Save Editors/SAV_SimpleTrainer.resx @@ -117,4 +117,100 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAE + AAAAAAAAAAAAAAAAAAAAAAAAIyMjAQAAAAALCwsPJiYmJysrKycqKionKSkpJykpKScpKSknKioqJyoq + KicrKysnJycnJw0ODQ8AAAAAJiYmAQAAAABpaWlHq6ur17+/v+6+vr7svr6+7b6+vu2+vr7tvr6+7b6+ + vu2+vr7tvr6+7L+/v+6rq6vXampqSAAAAAAoKSgXvr++3eLi4v/g4OD94eHh/+Hh4f/i4uL/4uLi/+Li + 4v/i4uL/4eHh/+Dh4P/g4OD94uLi/7+/v90sLCwXfn5+PNna2frg4OD/39/f/uHh4f7h4eH+39/f/uDg + 4P7g4OD+39/f/uHh4f7h4OH+39/f/t/g3//a2tr6g4ODPoOCgz7X19f64+Pj/+Li4v7k5OT/4+Tj//Ly + 8v/19fX/9PT0//T09P/k5OT/5OTk/+Pj4/7j4+P/19jX+4qLikCDhIM+2tra++Xl5f/k5eT+5OTk//Lz + 8v+urq7/RUVF/z4+Pv+Zmpn/8fHx/+Xm5f/k5eT+5eXl/9ra2vyLi4tAhYWFPuXm5vvx8vP/7+/w/v// + //+sra3/AgIC/15eXv9tbG3/BQUF/4yMjP//////7+/w/vHy8//l5ub8jY2NQC4uLD5LS0f7UFBL/09P + Sv5YWVP/FBUS/29wcP///////////5SUlP8PDw//U1NO/1BQS/5PT0r/S0tH/DIyMEAAAAs+AAAM+wAA + Dv8AAA/+AwMS/wAAAP+UlJX///////////+3t7n/AAAA/wAAD/8BAQ/+AAAO/wAADPwCAg5ABARSPgoK + k/sNDab/DQ2o/hAQvP8CAmj/IiIW/7Kzrv/Cw8D/NDQm/wAATf8QELz/DQ2q/gwMp/8LC5T8Dg5bQAUF + Xj4KCpz7DQ2u/w0NsP4NDbX/Dw+//wUFYf8CAhL/AwMP/wMDTf8ODrj/Dg64/w0NsP4MDK7/Cwud/A8P + aEEGBmU9DAyl+w4Otf8ODrf+Dw+6/xAQvv8TE8v/EhK+/xAQvP8TE8v/EBDA/w8Puf8PD7f+Dg61/w0N + pvsREW9ACAhtQA8PsfsTE77/ExO//xQUwP8UFML/FBTD/xUVyP8WFsn/FRXE/xQUw/8UFMH/ExO//xMT + vv8QELL7ERF3QxkZdCgXF771ExPH/xUVyPwVFcn9FhbL/RcXzP0XF8z9FxfM/RcXy/0XF8v9FhbJ/RUV + yPwTE8f/Fxe+9RkZdykAAAAAIyOtghsbx/8ZGcj+GRnJ/xoayf8aGsn/GhrK/xoayv8aGsn/GhrJ/xkZ + yf8ZGcj+GxvH/yMjrYQAAAAAAADHAQAAAAAzM51FLCyscCoqrGwqKqxtKSmsbSoqrG0qKqxtKSmsbSoq + rG0qKqxsLCyscDMznUUAAAAAAAAAAP//AADAAwAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB + AACAAQAAgAEAAIABAACAAQAAgAEAAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKysrCR0dHSMWFhY3GBgYORgYGDkYGBg5GBgYORgY + GDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5FxcXNx4e + HiQuLi4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASEhIARYWFis7OzuVkJCQ2ampqeqqqqrsqqqq7Kqq + quyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqq + quypqanqkZGR2j09PZcXFxcsUFBQAQAAAAAAAAAAAAAAAAAAAAASEhIuhISEytvb2/7W1tb/19fX/9jY + 2P/Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/9nZ2f/Y2Nj/2NjY/9jY + 2P/Y2Nj/2NjY/9fX1//W1tb/29vb/oeHh8sTExMvAAAAAAAAAAAAAAAAPDw8DGtra6zZ2dn/2dnZ/9ra + 2v/b29v/29vb/9vb2//c3Nz/3Nzc/9zc3P/c3Nz/3d3d/93d3f/d3d3/3d3d/93d3f/d3d3/3Nzc/9zc + 3P/c3Nz/3Nzc/9vb2//b29v/29vb/9ra2v/Z2dn/2dnZ/21tba5DQ0MNAAAAAAAAAAAiIiIx1NXU9tna + 2f/c3Nz/3d3d/93e3f/e3t7/3t7e/9/f3//f39//39/f/9/g3//g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg + 4P/g4OD/39/f/9/f3//f39//3t/e/97e3v/d3t3/3d3d/9zc3P/Z2tn/1dXV9icnJzMAAAAAAAAAAFhZ + WFzf4N//3Nzc/97e3v/f39//39/f/9/g3//g4OD/4ODg/+Hh4f/h4eH/4eHh/+Li4v/i4uL/4uLi/+Li + 4v/i4uL/4uLi/+Hi4f/h4eH/4eHh/+Dg4P/g4OD/3+Df/9/f3//f39//3t7e/9zc3P/f39//XV1dXQAA + AAAAAAAAZmZmZdvc2//e3t7/3+Df/+Dg4P/g4eD/4eHh/+Hi4f/i4uL/4uPi/+Pj4//j4+P/5OTk/+Tk + 5P/k5OT/5OTk/+Tk5P/k5OT/4+Pj/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/f4N//3t7e/9vb + 2/9wcHBoAAAAAAAAAABoaGhl3d3d/9/f3//h4eH/4eLh/+Li4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl + 5f/l5uX/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh + 4f/f39//3N3c/3Nzc2kAAAAAAAAAAGhoaGXe3t7/4ODg/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm + 5v/m5+b/5+fn/+fn5//n6Of/6Ojo/+jo6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pk + 4//j4+P/4uLi/+Dg4P/e3t7/c3NzaQAAAAAAAAAAaGhoZd/g3//i4uL/5OTk/+Tl5P/l5eX/5ebl/+bn + 5v/n5+f/5+jn/+jp6P/p6en/7Ozs/8LCwv+Tk5P/ioqK/66urv/o6ej/6enp/+jp6P/o6Oj/5+jn/+bn + 5v/m5ub/5ebl/+Tl5P/k5OT/4uLi/9/g3/9zdHNpAAAAAAAAAABoaWhl4eLh/+Pk4//m5ub/5ubm/+fn + 5//n6Of/6Ojo/+np6f/p6un/6urq/8bGxv8yMjL/AAAA/wAAAP8AAAD/AAAA/xMTE/+ZmZn/7Ozs/+rq + 6v/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/k5OT/4eHh/3R0dGkAAAAAAAAAAGhpaGXj4+P/5eXl/+fn + 5//n6Of/6Ojo/+np6f/q6ur/6urq/+vr6//Dw8P/DAwM/wAAAP8AAAD/Gxsb/ygoKP8BAQH/AAAA/wAA + AP+FhYX/7O3s/+rr6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+Xl5f/i4+L/dHR0aQAAAAAAAAAAYWFhZeTl + 5P/m5+b/6Ono/+np6f/p6un/6uvq/+vr6//s7Oz/7e7t/ycnJ/8AAAD/Ghoa/7S0tP/m5ub/5OTk/9HR + 0f9GRkb/AAAA/wICAv/IyMj/7Ozs/+vs6//q6+r/6urq/+nq6f/o6ej/5+fn/+Tk5P9sbGxpAAAAAAAA + AAA9Pj1lj4+P/5OTk/+VlZX/lpaW/5eXl/+YmJj/mZmZ/5qamv92dnb/AAAA/wEBAf+/wL//3Nzc/+Tk + 5P/l5eX/3d3d/+Li4v8mJib/AAAA/0ZGRv+ampr/mZmZ/5iYmP+Xl5f/lpaW/5WVlf+Tk5P/j4+P/0ZG + RmoAAAAAAAAAAAwMDGUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Nzc3/+fn + 5//q6ur/7O3s/+zt7P/v7+//39/f/4WFhf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8AAAD/EBAQagAAAAAAAAAAAwMHZQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP9NTU3/5ufm//Lz8v/z9PP/8/Tz//X19f/l5eX/nZ2d/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8AAAD/AAAA/wAAAP8GBgpqAAAAAAAAAAAAABZlAQEk/wEBJ/8CAin/AgIq/wICKv8CAiv/AgIs/wIC + LP8BAR3/AAAA/xwcHP/w8PD/6+zr//r6+v/6+vr/9PT0/+vr6/9lZWX/AAAA/wAAD/8CAi3/AgIs/wIC + K/8CAir/AgIq/wICKf8BASf/AQEl/wUFG2oAAAAAAAAAAAICQGUGBpL/Bwec/wgIo/8JCaf/CQmq/wkJ + rf8JCa//Cgqz/wkJqP8AAAL/AAAA/4CAgP/y8/L/6+zr/+3t7f/u7u7/xMTE/wcHB/8AAAD/BgZz/woK + s/8JCbD/CQmt/wkJqv8JCaj/CAik/wcHnf8HB5P/Dg5MagAAAAAAAAAAAwNHZQgIk/8JCZ3/Cgqj/wsL + p/8LC6n/Cwus/wsLr/8MDLL/DAy2/wYGW/8AAAD/AAAA/1JSUv+sraz/tra2/3h4eP8KCgr/AAAA/wIC + Iv8MDLb/DAyy/wsLsP8LC63/Cwuq/wsLp/8KCqT/CQmd/wgIk/8PD1VrAAAAAAAAAAAEBE1lCQmY/woK + ov8LC6j/DAyr/wwMrf8MDLD/DAyy/w0Ntf8NDbf/Dg67/wUFSv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA + AP8CAiH/DQ2q/w0NuP8NDbX/DQ2z/wwMsP8MDK7/DAyr/wsLqP8KCqL/CQmZ/xAQWmsAAAAAAAAAAAQE + UGUKCp7/Cwum/wwMrP8NDa//DQ2w/w0Ns/8ODrX/Dg63/w4Ouf8ODrv/Dw/A/wwMiv8FBTj/AAAG/wAA + AP8DAyb/CQls/w8Pu/8PD7z/Dg66/w4OuP8ODrX/DQ2z/w0Nsf8NDa//DAys/wsLp/8KCp7/ERFeawAA + AAAAAAAABQVTZQsLpP8MDKv/DQ2w/w4Os/8ODrT/Dg62/w8PuP8PD7r/Dw+8/w8Pvf8QEL//EBDA/xER + w/8SEsn/ERHJ/xERxf8QEMD/EBC//w8Pvv8PD7z/Dw+6/w8PuP8ODrf/Dg61/w4Os/8NDbH/DAyr/wsL + pP8SEmFrAAAAAAAAAAAGBlZlDAyq/w4OsP8PD7X/Dw+3/w8PuP8QELr/EBC7/xAQvf8REb7/ERHA/xER + wf8REcL/EhLC/xISw/8SEsP/EhLC/xERwv8REcH/ERHA/xERvv8QEL3/EBC7/xAQuv8QELj/Dw+3/w8P + tf8ODrD/DAyq/xMTZWsAAAAAAAAAAAcHWmUODrD/EBC2/xERuv8REbz/ERG9/xISvv8SEr//EhLA/xMT + wf8TE8P/ExPD/xMTxP8TE8X/FBTF/xQUxf8UFMX/ExPE/xMTxP8TE8P/ExPC/xISwf8SEr//EhK+/xER + vf8REbz/ERG6/xAQtv8ODrD/FBRpawAAAAAAAAAACAhcYxAQtf8SErv/ExO+/xQUwP8UFMD/FBTB/xUV + wv8VFcP/FRXE/xUVxf8WFsb/FhbG/xYWx/8WFsf/FhbH/xYWx/8WFsf/FhbG/xYWxf8VFcT/FRXD/xUV + wv8UFMH/FBTB/xQUwP8TE77/EhK7/xAQtf8TE2hoAAAAAAAAAAAQEFNUFRXC/xMTv/8UFMP/FRXE/xUV + xP8VFcX/FRXG/xYWx/8WFsf/FhbI/xYWyf8XF8n/FxfK/xcXyv8XF8r/FxfK/xcXyf8XF8n/FhbI/xYW + yP8WFsf/FhbG/xUVxf8VFcT/FRXE/xQUw/8TE7//FRXB/xAQV1UAAAAAAAAAAA0NPxkjI8byFBTD/xUV + x/8WFsj/FxfJ/xcXyf8XF8r/FxfK/xcXy/8YGMz/GBjM/xgYzP8YGM3/GBjN/xgYzf8YGM3/GBjM/xgY + zP8YGMz/GBjL/xcXy/8XF8r/FxfJ/xcXyf8WFsj/FRXH/xQUw/8jI8f0Dg5GGwAAAAAAAAAAFhZxAiUl + eIUZGcr/FBTI/xUVyv8WFsv/FhbM/xYWzP8WFsz/FhbN/xcXzf8XF83/FxfN/xcXzv8XF87/FxfO/xcX + zv8XF87/FxfN/xcXzf8WFs3/FhbM/xYWzP8WFsz/FhbL/xUVyv8UFMj/GBjJ/yYmeogWFnYCAAAAAAAA + AAAAAAAAGBh1BzMzk50kJNP+FxfK/xgYzP8YGMz/GBjN/xgYzf8YGM3/GBjN/xgYzf8ZGc7/GRnO/xkZ + zv8ZGc7/GRnO/xkZzv8YGM3/GBjN/xgYzf8YGM3/GBjN/xgYzP8YGMz/FxfK/yMj0v4zM5WfFBRkBwAA + AAAAAAAAAAAAAAAAAAAAAAAAHBx7Ay0tdkg3N5emMTGpxSwsp8gsLKfILCynyCwsp8gsLKfILCynyCws + p8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyDExqcU2NpenLi54Shsb + ewMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////8AAAD+AAAAfAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA + AAPAAAADwAAAA8AAAAPAAAAD4AAAB/gAAB////// + + \ No newline at end of file From 4d666aa2aab03c1efe126f486d1d85592bb28443 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Mon, 29 Aug 2016 20:34:02 -0700 Subject: [PATCH 10/16] Inventory editing for Gen I --- PKHeX/PKM/PKX.cs | 19 +++++++++++++++++++ PKHeX/Saves/SAV1.cs | 4 ++-- PKHeX/Saves/SaveUtil.cs | 3 +++ PKHeX/Subforms/Save Editors/SAV_Inventory.cs | 16 +++++++++++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/PKHeX/PKM/PKX.cs b/PKHeX/PKM/PKX.cs index 53facdc21..675679597 100644 --- a/PKHeX/PKM/PKX.cs +++ b/PKHeX/PKM/PKX.cs @@ -2121,6 +2121,25 @@ public static ushort getG4Item(ushort g3val) }; #endregion + #region Gen 1 Item Table + public static string[] getG1ItemList() + { + return new[] { "(None)", "Master Ball", "Ultra Ball", "Great Ball", "Poké Ball", "Town Map", "Bicycle", "????? (7)", "Safari Ball", "Pokédex", "Moon Stone", "Antidote", "Burn Heal", "Ice Heal", "Awakening", "Parlyz Heal", "Full Restore", "Max Potion", "Hyper Potion", "Super Potion", "Potion", "BoulderBadge", "CascadeBadge", "ThunderBadge", "RainbowBadge", "SoulBadge", "MarshBadge", "VolcanoBadge", "EarthBadge", "Escape Rope", "Repel", "Old Amber", "Fire Stone", "Thunder Stone", "Water Stone", "HP Up", "Protein", "Iron", "Carbos", "Calcium", "Rare Candy", "Dome Fossil", "Helix Fossil", "Secret Key", "????? (44)", "Bike Voucher", "X Accuracy", "Leaf Stone", "Card Key", "Nugget", "PP Up (Unused)", "Poké Doll", "Full Heal", "Revive", "Max Revive", "Guard Spec.", "Super Repel", "Max Repel", "Dire Hit", "Coin", "Fresh Water", "Soda Pop", "Lemonade", "S.S. Ticket", "Gold Teeth", "X Attack", "X Defend", "X Speed", "X Special", "Coin Case", "Oak's Parcel", "Itemfinder", "Silph Scope", "Poké Flute", "Lift Key", "Exp. All", "Old Rod", "Good Rod", "Super Rod", "PP Up", "Ether", "Max Ether", "Elixer", "Max Elixer", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "HM01", "HM02", "HM03", "HM04", "HM05", "TM01", "TM02", "TM03", "TM04", "TM05", "TM06", "TM07", "TM08", "TM09", "TM10", "TM11", "TM12", "TM13", "TM14", "TM15", "TM16", "TM17", "TM18", "TM19", "TM20", "TM21", "TM22", "TM23", "TM24", "TM25", "TM26", "TM27", "TM28", "TM29", "TM30", "TM31", "TM32", "TM33", "TM34", "TM35", "TM36", "TM37", "TM38", "TM39", "TM40", "TM41", "TM42", "TM43", "TM44", "TM45", "TM46", "TM47", "TM48", "TM49", "TM50", "TM51", "TM52", "TM53", "TM54", "TM55" }; + } + + #endregion + public static int[] getG1LegalItems() + { + return Enumerable.Range(0, 7) // 0-6 + .Concat(Enumerable.Range(10, 11)) // 10-20 + .Concat(Enumerable.Range(29, 15)) // 29-43 + .Concat(Enumerable.Range(45, 5)) // 45-49 + .Concat(Enumerable.Range(51, 8)) // 51-58 + .Concat(Enumerable.Range(60, 24)) // 60-83 + .Concat(Enumerable.Range(196, 54)) // 196-249 + .ToArray(); + } + public static int getG1Species(int raw_id) { int[] table = { 0x00, 0x70, 0x73, 0x20, 0x23, 0x15, 0x64, 0x22, 0x50, 0x02, 0x67, 0x6C, 0x66, 0x58, 0x5E, 0x1D, 0x1F, 0x68, 0x6F, 0x83, 0x3B, 0x97, 0x82, 0x5A, 0x48, 0x5C, 0x7B, 0x78, 0x09, 0x7F, 0x72, 0x00, 0x00, 0x3A, 0x5F, 0x16, 0x10, 0x4F, 0x40, 0x4B, 0x71, 0x43, 0x7A, 0x6A, 0x6B, 0x18, 0x2F, 0x36, 0x60, 0x4C, 0x00, 0x7E, 0x00, 0x7D, 0x52, 0x6D, 0x00, 0x38, 0x56, 0x32, 0x80, 0x00, 0x00, 0x00, 0x53, 0x30, 0x95, 0x00, 0x00, 0x00, 0x54, 0x3C, 0x7C, 0x92, 0x90, 0x91, 0x84, 0x34, 0x62, 0x00, 0x00, 0x00, 0x25, 0x26, 0x19, 0x1A, 0x00, 0x00, 0x93, 0x94, 0x8C, 0x8D, 0x74, 0x75, 0x00, 0x00, 0x1B, 0x1C, 0x8A, 0x8B, 0x27, 0x28, 0x85, 0x88, 0x87, 0x86, 0x42, 0x29, 0x17, 0x2E, 0x3D, 0x3E, 0x0D, 0x0E, 0x0F, 0x00, 0x55, 0x39, 0x33, 0x31, 0x57, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x44, 0x00, 0x37, 0x61, 0x2A, 0x96, 0x8F, 0x81, 0x00, 0x00, 0x59, 0x00, 0x63, 0x5B, 0x00, 0x65, 0x24, 0x6E, 0x35, 0x69, 0x00, 0x5D, 0x3F, 0x41, 0x11, 0x12, 0x79, 0x01, 0x03, 0x49, 0x00, 0x76, 0x77, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x4E, 0x13, 0x14, 0x21, 0x1E, 0x4A, 0x89, 0x8E, 0x00, 0x51, 0x00, 0x00, 0x04, 0x07, 0x05, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x2C, 0x2D, 0x45, 0x46, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; diff --git a/PKHeX/Saves/SAV1.cs b/PKHeX/Saves/SAV1.cs index e94815e49..546a0987e 100644 --- a/PKHeX/Saves/SAV1.cs +++ b/PKHeX/Saves/SAV1.cs @@ -343,7 +343,7 @@ public uint Coin } } - private readonly ushort[] LegalItems = Enumerable.Range(1, 255).Select(i => (ushort)i).ToArray(); + private readonly ushort[] LegalItems = PKX.getG1LegalItems().Select(i => (ushort)i).ToArray(); public override InventoryPouch[] Inventory { get @@ -352,7 +352,7 @@ public override InventoryPouch[] Inventory InventoryPouch[] pouch = { new InventoryPouch(InventoryType.Items, legalItems, 99, (Japanese ? 0x25C4 : 0x25C9), 20), - new InventoryPouch(InventoryType.Items, legalItems, 99, (Japanese ? 0x27DC : 0x27E6), 50), + new InventoryPouch(InventoryType.MailItems, legalItems, 99, (Japanese ? 0x27DC : 0x27E6), 50) }; foreach (var p in pouch) { diff --git a/PKHeX/Saves/SaveUtil.cs b/PKHeX/Saves/SaveUtil.cs index f8d7db77e..9102c5627 100644 --- a/PKHeX/Saves/SaveUtil.cs +++ b/PKHeX/Saves/SaveUtil.cs @@ -215,6 +215,9 @@ public static GameVersion getVersionGroup(GameVersion Version) case GameVersion.CXD: return GameVersion.CXD; + case GameVersion.RBY: + return GameVersion.RBY; + case GameVersion.R: case GameVersion.S: return GameVersion.RS; diff --git a/PKHeX/Subforms/Save Editors/SAV_Inventory.cs b/PKHeX/Subforms/Save Editors/SAV_Inventory.cs index b9094f50a..c997680e7 100644 --- a/PKHeX/Subforms/Save Editors/SAV_Inventory.cs +++ b/PKHeX/Subforms/Save Editors/SAV_Inventory.cs @@ -10,7 +10,19 @@ public SAV_Inventory() { InitializeComponent(); Util.TranslateInterface(this, Main.curlanguage); - itemlist = SAV.Generation == 3 ? Main.g3items : Main.itemlist; + switch (SAV.Generation) + { + case 1: + itemlist = PKX.getG1ItemList(); + B_GiveAll.Visible = false; // Can't give all, not enough room + break; + case 3: + itemlist = Main.g3items; + break; + default: + itemlist = Main.itemlist; + break; + } Pouches = SAV.Inventory; getBags(); } @@ -155,6 +167,8 @@ private void packBags() itemcnt++; // No 0 count of items else if (itemcnt > 995) itemcnt = 995; // cap out + else if (itemcnt > 99 && SAV.Generation < 3) + itemcnt = 99; if (itemindex == 0) // Compression of Empty Slots continue; From b6b931220d0c045be1ad9d0639ddf6ce15c299d7 Mon Sep 17 00:00:00 2001 From: Kaphotics Date: Tue, 30 Aug 2016 20:31:14 -0700 Subject: [PATCH 11/16] Separate out QR web requests Moved to Util --- PKHeX/Misc/QR.cs | 12 ++---------- PKHeX/PKHeX.csproj | 1 + PKHeX/Util/NetUtil.cs | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 PKHeX/Util/NetUtil.cs diff --git a/PKHeX/Misc/QR.cs b/PKHeX/Misc/QR.cs index ebf8dc130..e4df20778 100644 --- a/PKHeX/Misc/QR.cs +++ b/PKHeX/Misc/QR.cs @@ -1,7 +1,5 @@ using System; using System.Drawing; -using System.IO; -using System.Net; using System.Web; using System.Windows.Forms; @@ -57,10 +55,7 @@ internal static byte[] getQRData() string webURL = "http://api.qrserver.com/v1/read-qr-code/?fileurl=" + HttpUtility.UrlEncode(address); try { - HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webURL); - HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse(); - var reader = new StreamReader(httpWebReponse.GetResponseStream()); - string data = reader.ReadToEnd(); + string data = Util.getStringFromURL(webURL); if (data.Contains("could not find")) { Util.Alert("Reader could not find QR data in the image."); return null; } if (data.Contains("filetype not supported")) { Util.Alert("Input URL is not valid. Double check that it is an image (jpg/png).", address); return null; } // Quickly convert the json response to a data string @@ -82,10 +77,7 @@ internal static Image getQRImage(byte[] data, string server) try { - HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webURL); - HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse(); - Stream stream = httpWebReponse.GetResponseStream(); - if (stream != null) return Image.FromStream(stream); + return Util.getImageFromURL(webURL); } catch { diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index eae839e4b..8780ef3be 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -304,6 +304,7 @@ + diff --git a/PKHeX/Util/NetUtil.cs b/PKHeX/Util/NetUtil.cs new file mode 100644 index 000000000..d013c8b25 --- /dev/null +++ b/PKHeX/Util/NetUtil.cs @@ -0,0 +1,41 @@ +using System; +using System.Drawing; +using System.IO; +using System.Net; + +namespace PKHeX +{ + public partial class Util + { + public static string getStringFromURL(string webURL) + { + try + { + HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webURL); + HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse(); + var reader = new StreamReader(httpWebReponse.GetResponseStream()); + return reader.ReadToEnd(); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return null; + } + } + public static Image getImageFromURL(string webURL) + { + try + { + HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webURL); + HttpWebResponse httpWebReponse = (HttpWebResponse)httpWebRequest.GetResponse(); + Stream stream = httpWebReponse.GetResponseStream(); + return stream != null ? Image.FromStream(stream) : null; + } + catch (Exception e) + { + Console.WriteLine(e.Message); + return null; + } + } + } +} From 14b4bfb2f4bb21e0d2778b0b29e809f0c33c9b7e Mon Sep 17 00:00:00 2001 From: Kaphotics Date: Tue, 30 Aug 2016 21:12:47 -0700 Subject: [PATCH 12/16] Add update available indication version.txt as a program resource -> check against online copy, if online has an earlier date then indicate that an update is available. When posting a new update, the version.txt has to be updated with a new yyyyMMdd. Ask me on IRC why I prefer to do things this way ;) --- PKHeX/MainWindow/Main.Designer.cs | 28 ++++++++++-------- PKHeX/MainWindow/Main.cs | 41 +++++++++++++++++++++++--- PKHeX/MainWindow/Main.resx | 6 ++-- PKHeX/PKHeX.csproj | 3 ++ PKHeX/Properties/Resources.Designer.cs | 9 ++++++ PKHeX/Properties/Resources.resx | 3 ++ PKHeX/Resources/text/version.txt | 1 + 7 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 PKHeX/Resources/text/version.txt diff --git a/PKHeX/MainWindow/Main.Designer.cs b/PKHeX/MainWindow/Main.Designer.cs index ed26d445d..b46c66d52 100644 --- a/PKHeX/MainWindow/Main.Designer.cs +++ b/PKHeX/MainWindow/Main.Designer.cs @@ -245,7 +245,6 @@ public void InitializeComponent() this.Menu_ModifyPKM = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_Unicode = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_About = new System.Windows.Forms.ToolStripMenuItem(); - this.L_Save = new System.Windows.Forms.Label(); this.tabBoxMulti = new System.Windows.Forms.TabControl(); this.Tab_Box = new System.Windows.Forms.TabPage(); this.PAN_Box = new System.Windows.Forms.Panel(); @@ -363,6 +362,7 @@ public void InitializeComponent() this.mnuLQR = new System.Windows.Forms.ToolStripMenuItem(); this.mnuLSave = new System.Windows.Forms.ToolStripMenuItem(); this.PB_Legal = new System.Windows.Forms.PictureBox(); + this.L_UpdateAvailable = new System.Windows.Forms.LinkLabel(); this.tabMain.SuspendLayout(); this.Tab_Main.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.Label_IsShiny)).BeginInit(); @@ -2985,16 +2985,6 @@ public void InitializeComponent() this.Menu_About.Text = "About &PKHeX"; this.Menu_About.Click += new System.EventHandler(this.mainMenuAbout); // - // L_Save - // - this.L_Save.AutoSize = true; - this.L_Save.Location = new System.Drawing.Point(300, 5); - this.L_Save.Name = "L_Save"; - this.L_Save.Size = new System.Drawing.Size(54, 13); - this.L_Save.TabIndex = 4; - this.L_Save.Text = "SAV: N/A"; - this.L_Save.Click += new System.EventHandler(this.clickSaveFileName); - // // tabBoxMulti // this.tabBoxMulti.Controls.Add(this.Tab_Box); @@ -4604,16 +4594,28 @@ public void InitializeComponent() this.PB_Legal.TabStop = false; this.PB_Legal.Click += new System.EventHandler(this.clickLegality); // + // L_UpdateAvailable + // + this.L_UpdateAvailable.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.L_UpdateAvailable.Location = new System.Drawing.Point(305, 5); + this.L_UpdateAvailable.Name = "L_UpdateAvailable"; + this.L_UpdateAvailable.Size = new System.Drawing.Size(300, 13); + this.L_UpdateAvailable.TabIndex = 102; + this.L_UpdateAvailable.TabStop = true; + this.L_UpdateAvailable.Text = "New Update Available!"; + this.L_UpdateAvailable.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.L_UpdateAvailable.Visible = false; + // // Main // this.AllowDrop = true; this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(614, 361); + this.Controls.Add(this.L_UpdateAvailable); this.Controls.Add(this.PB_Legal); this.Controls.Add(this.dragout); this.Controls.Add(this.tabBoxMulti); - this.Controls.Add(this.L_Save); this.Controls.Add(this.tabMain); this.Controls.Add(this.menuStrip1); this.Controls.Add(this.GB_SAVtools); @@ -4884,7 +4886,6 @@ public void InitializeComponent() private System.Windows.Forms.Label L_Characteristic; private System.Windows.Forms.TextBox TB_IVTotal; private System.Windows.Forms.Label L_Potential; - private System.Windows.Forms.Label L_Save; private System.Windows.Forms.TabControl tabBoxMulti; private System.Windows.Forms.TabPage Tab_Box; private System.Windows.Forms.TabPage Tab_PartyBattle; @@ -5085,6 +5086,7 @@ public void InitializeComponent() private System.Windows.Forms.FlowLayoutPanel FLP_PKMEditors; private System.Windows.Forms.Button B_LinkInfo; private System.Windows.Forms.Button B_CGearSkin; + private System.Windows.Forms.LinkLabel L_UpdateAvailable; } } diff --git a/PKHeX/MainWindow/Main.cs b/PKHeX/MainWindow/Main.cs index f91ed9125..817610a0c 100644 --- a/PKHeX/MainWindow/Main.cs +++ b/PKHeX/MainWindow/Main.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Drawing; +using System.Globalization; using System.IO; using System.Linq; using System.Media; @@ -19,6 +20,31 @@ public Main() new Thread(() => new SplashScreen().ShowDialog()).Start(); DragInfo.slotPkmSource = SAV.BlankPKM.EncryptedPartyData; InitializeComponent(); + + // Check for Updates + L_UpdateAvailable.Click += (sender, e) => { Process.Start(ThreadPath); }; + new Thread(() => + { + string data = Util.getStringFromURL(VersionPath); + if (data == null) + return; + try + { + DateTime upd = DateTime.ParseExact(data, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); + DateTime cur = DateTime.ParseExact(Properties.Resources.ProgramVersion, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None); + + if (upd <= cur) + return; + + string message = $"New Update Available! {upd.ToString("d")}"; + if (InvokeRequired) + try { Invoke((MethodInvoker) delegate { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; }); } + catch { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; } + else { L_UpdateAvailable.Visible = true; L_UpdateAvailable.Text = message; } + } + catch { } + }).Start(); + CB_ExtraBytes.SelectedIndex = 0; SaveFile.SetUpdateDex = Menu_ModifyDex.Checked; SaveFile.SetUpdatePKM = Menu_ModifyPKM.Checked; @@ -184,6 +210,8 @@ public Main() public static string DatabasePath => Path.Combine(WorkingDirectory, "db"); private static string WC6DatabasePath => Path.Combine(WorkingDirectory, "wc6"); private static string BackupPath => Path.Combine(WorkingDirectory, "bak"); + private static string ThreadPath => @"https://projectpokemon.org/forums/showthread.php?36986"; + private static string VersionPath => @"https://raw.githubusercontent.com/kwsch/PKHeX/master/PKHeX/Resources/Text/version.txt"; #endregion @@ -756,7 +784,7 @@ private void loadSAV(SaveFile sav, string path) SAV.FileName = Path.GetExtension(path) == ".bak" ? Path.GetFileName(path).Split(new[] { " [" }, StringSplitOptions.None)[0] : Path.GetFileName(path); - L_Save.Text = $"SAV{SAV.Generation}: {Path.GetFileNameWithoutExtension(Util.CleanFileName(SAV.BAKName))}"; // more descriptive + Text = "PKHeX - " + $"SAV{SAV.Generation}: {Path.GetFileNameWithoutExtension(Util.CleanFileName(SAV.BAKName))}"; // more descriptive // If backup folder exists, save a backup. string backupName = Path.Combine(BackupPath, Util.CleanFileName(SAV.BAKName)); @@ -769,7 +797,7 @@ private void loadSAV(SaveFile sav, string path) { SAV.FilePath = null; SAV.FileName = "Blank Save File"; - L_Save.Text = $"SAV{SAV.Generation}: {SAV.FileName} [{SAV.OT} ({SAV.Version})]"; + Text = "PKHeX - " + $"SAV{SAV.Generation}: {SAV.FileName} [{SAV.OT} ({SAV.Version})]"; GB_SAVtools.Visible = false; } @@ -2622,7 +2650,7 @@ private void clickBoxLeft(object sender, EventArgs e) } private void clickBoxSort(object sender, EventArgs e) { - if (tabBoxMulti.SelectedIndex != 0) + if (tabBoxMulti.SelectedTab != Tab_Box) return; if (!SAV.HasBox) return; @@ -2665,7 +2693,12 @@ private void clickBoxSort(object sender, EventArgs e) } private void clickBoxDouble(object sender, MouseEventArgs e) { - if (tabBoxMulti.SelectedIndex != 0) + if (tabBoxMulti.SelectedTab == Tab_SAV) + { + clickSaveFileName(sender, e); + return; + } + if (tabBoxMulti.SelectedTab != Tab_Box) return; if (!SAV.HasBox) return; diff --git a/PKHeX/MainWindow/Main.resx b/PKHeX/MainWindow/Main.resx index 1d654adaa..df010947a 100644 --- a/PKHeX/MainWindow/Main.resx +++ b/PKHeX/MainWindow/Main.resx @@ -877,9 +877,6 @@ True - - True - True @@ -1332,6 +1329,9 @@ SiSLGvswRQAAAABJRU5ErkJggg== + + True + True diff --git a/PKHeX/PKHeX.csproj b/PKHeX/PKHeX.csproj index 8780ef3be..f4eab194c 100644 --- a/PKHeX/PKHeX.csproj +++ b/PKHeX/PKHeX.csproj @@ -2720,6 +2720,9 @@ + + +