mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 14:30:56 +00:00
Implement PK1 loading/editing/saving.
This commit is contained in:
parent
4738a2c716
commit
8cfe57d504
8 changed files with 93 additions and 23 deletions
|
@ -237,7 +237,7 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
}
|
||||
private void updateRandomEVs(object sender, EventArgs e)
|
||||
{
|
||||
changingFields = true;
|
||||
if (ModifierKeys == Keys.Control || ModifierKeys == Keys.Shift)
|
||||
{
|
||||
// Max EVs
|
||||
|
@ -1706,6 +1725,8 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
}
|
||||
}
|
||||
// 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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
// 00s present in slot.
|
||||
pb.Image = null;
|
||||
pb.BackColor = Color.Transparent;
|
||||
pb.Visible = true;
|
||||
return;
|
||||
}
|
||||
PKM p = SAV.getStoredSlot(offset);
|
||||
|
@ -3108,11 +3133,13 @@ namespace PKHeX
|
|||
// 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)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX
|
||||
{
|
||||
|
@ -94,7 +95,6 @@ namespace PKHeX
|
|||
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
|
||||
|
|
|
@ -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 @@ namespace PKHeX
|
|||
|
||||
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 @@ namespace PKHeX
|
|||
|
||||
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 @@ namespace PKHeX
|
|||
{
|
||||
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 @@ namespace PKHeX
|
|||
{
|
||||
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 @@ namespace PKHeX
|
|||
// 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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
{
|
||||
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);
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace PKHeX
|
|||
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 }; }
|
||||
|
|
|
@ -31,6 +31,9 @@ namespace PKHeX
|
|||
|
||||
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 @@ namespace PKHeX
|
|||
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 @@ namespace PKHeX
|
|||
+ "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 @@ namespace PKHeX
|
|||
ushort chk = 0;
|
||||
switch (format)
|
||||
{
|
||||
case 1:
|
||||
case 3: // TOneverDO, nobody exports encrypted pk3s
|
||||
return;
|
||||
case 4:
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace PKHeX
|
|||
/// <returns>A boolean indicating whether or not the length is valid for a Pokemon file.</returns>
|
||||
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 @@ namespace PKHeX
|
|||
{"ぷ", 0x46},
|
||||
{"ぺ", 0x47},
|
||||
{"ぽ", 0x48},
|
||||
{"\0", 0x50},
|
||||
{"トレーナー", 0x5D},
|
||||
{"ア", 0x80},
|
||||
{"イ", 0x81},
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace PKHeX
|
|||
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace PKHeX
|
|||
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);
|
||||
|
|
Loading…
Reference in a new issue