mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-09 18:27:03 -05:00
Sync basic gen3 support
Still many things not yet working (item/inventory editing needs new string resources)
This commit is contained in:
36
Legality/Tables3.cs
Normal file
36
Legality/Tables3.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX
|
||||
{
|
||||
public static partial class Legal
|
||||
{
|
||||
// PKHeX Valid Array Storage
|
||||
#region DP
|
||||
internal static readonly ushort[] Pouch_Items_RS = {
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 93, 94, 95, 96, 97, 98, 103, 104, 106, 107, 108, 109, 110, 111, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 254, 255, 256, 257, 258
|
||||
};
|
||||
internal static readonly ushort[] Pouch_Key_RS = {
|
||||
259, 260, 261, 262, 263, 264, 265, 266, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288
|
||||
};
|
||||
internal static readonly ushort[] Pouch_TM_RS = {
|
||||
289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338,
|
||||
};
|
||||
internal static readonly ushort[] Pouch_HM_RS = {
|
||||
339, 340, 341, 342, 343, 344, 345, 346
|
||||
};
|
||||
internal static readonly ushort[] Pouch_Berries_RS = {
|
||||
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175
|
||||
};
|
||||
internal static readonly ushort[] Pouch_Ball_RS = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
|
||||
};
|
||||
internal static readonly ushort[] Pouch_Key_E = Pouch_Key_RS.Concat(new ushort[] { 375, 376 }).ToArray();
|
||||
internal static readonly ushort[] Pouch_Key_FRLG = Pouch_Key_RS.Concat(new ushort[] { 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374 }).ToArray();
|
||||
|
||||
internal static readonly ushort[] Pouch_TMHM_RS = Pouch_TM_RS.Concat(Pouch_HM_RS).ToArray();
|
||||
internal static readonly ushort[] HeldItems_RS = new ushort[1].Concat(Pouch_Items_RS).Concat(Pouch_Ball_RS).Concat(Pouch_Berries_RS).Concat(Pouch_TM_RS).ToArray();
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,7 @@
|
||||
<Compile Include="Legality\Checks.cs" />
|
||||
<Compile Include="Legality\Core.cs" />
|
||||
<Compile Include="Legality\Data.cs" />
|
||||
<Compile Include="Legality\Tables3.cs" />
|
||||
<Compile Include="Legality\Tables5.cs" />
|
||||
<Compile Include="Legality\Tables4.cs" />
|
||||
<Compile Include="MysteryGifts\MysteryGift.cs" />
|
||||
@@ -92,6 +93,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Saves\BlockInfo.cs" />
|
||||
<Compile Include="Saves\Inventory.cs" />
|
||||
<Compile Include="Saves\SAV3.cs" />
|
||||
<Compile Include="Saves\SAV4.cs" />
|
||||
<Compile Include="Saves\SAV5.cs" />
|
||||
<Compile Include="Saves\SAV6.cs" />
|
||||
|
||||
17
PKM/PK3.cs
17
PKM/PK3.cs
@@ -5,6 +5,10 @@ namespace PKHeX
|
||||
{
|
||||
public class PK3 : PKM // 3rd Generation PKM File
|
||||
{
|
||||
internal static readonly byte[] ExtraBytes =
|
||||
{
|
||||
0x2A, 0x2B
|
||||
};
|
||||
public override int SIZE_PARTY => PKX.SIZE_3PARTY;
|
||||
public override int SIZE_STORED => PKX.SIZE_3STORED;
|
||||
public override int Format => 3;
|
||||
@@ -22,7 +26,8 @@ public PK3(byte[] decryptedData = null, string ident = null)
|
||||
public override uint EncryptionConstant { get { return PID; } set { } }
|
||||
public override int Nature { get { return (int)(PID % 25); } set { } }
|
||||
public override int AltForm { get { return -1; } set { } }
|
||||
public override bool IsNicknamed { get { return Nickname != PKX.getSpeciesName(Species, Language); } set { } }
|
||||
|
||||
public override bool IsNicknamed { get { return PKX.getIsNicknamed(Species, Nickname); } set { } }
|
||||
public override int Gender { get { return PKX.getGender(Species, PID); } set { } }
|
||||
public override int Characteristic => -1;
|
||||
public override int CurrentFriendship { get { return OT_Friendship; } set { OT_Friendship = value; } }
|
||||
@@ -41,7 +46,7 @@ public PK3(byte[] decryptedData = null, string ident = null)
|
||||
if (strdata.Length > 10)
|
||||
Array.Resize(ref strdata, 10);
|
||||
strdata.CopyTo(Data, 0x08); } }
|
||||
public override int Language { get { return BitConverter.ToUInt16(Data, 0x12); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x12); } }
|
||||
public override int Language { get { return BitConverter.ToUInt16(Data, 0x12) & 0xFF; } set { BitConverter.GetBytes((ushort)(value | 0x200)).CopyTo(Data, 0x12); } }
|
||||
public override string OT_Name {
|
||||
get { return PKX.getG3Str(Data.Skip(0x14).Take(7).ToArray(), Japanese); }
|
||||
set { byte[] strdata = PKX.setG3Str(value, Japanese);
|
||||
@@ -55,7 +60,9 @@ public PK3(byte[] decryptedData = null, string ident = null)
|
||||
|
||||
#region Block A
|
||||
public override int Species { get { return PKX.getG4Species(BitConverter.ToUInt16(Data, 0x20)); } set { BitConverter.GetBytes((ushort)PKX.getG3Species(value)).CopyTo(Data, 0x20); } }
|
||||
public override int HeldItem { get { return BitConverter.ToUInt16(Data, 0x22); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x22); } }
|
||||
public override int HeldItem { get { return PKX.getG4Item((ushort)G3Item); } set { } }
|
||||
public int G3Item { get { return PKX.getG4Item(BitConverter.ToUInt16(Data, 0x22)); } set { BitConverter.GetBytes((ushort) value).CopyTo(Data, 0x22); } }
|
||||
|
||||
public override uint EXP { get { return BitConverter.ToUInt32(Data, 0x24); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x24); } }
|
||||
private byte PPUps { get { return Data[0x28]; } set { Data[0x28] = value; } }
|
||||
public override int Move1_PPUps { get { return (PPUps >> 0) & 3; } set { PPUps = (byte)((PPUps & ~(3 << 0)) | value); } }
|
||||
@@ -154,7 +161,7 @@ public PK3(byte[] decryptedData = null, string ident = null)
|
||||
|
||||
public override byte[] Encrypt()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return PKX.encryptArray3(Data);
|
||||
}
|
||||
public override bool getGenderIsValid()
|
||||
{
|
||||
@@ -277,7 +284,7 @@ public PK4 convertToPK4()
|
||||
// Set Final Data
|
||||
pk4.Met_Level = PKX.getLevel(pk4.Species, pk4.EXP);
|
||||
pk4.Gender = PKX.getGender(pk4.Species, pk4.PID);
|
||||
pk4.IsNicknamed |= pk4.Nickname != PKX.getSpeciesName(pk4.Species, pk4.Language);
|
||||
pk4.IsNicknamed = IsNicknamed;
|
||||
|
||||
// Unown Form
|
||||
if (Species == 201)
|
||||
|
||||
17
PKM/PKM.cs
17
PKM/PKM.cs
@@ -19,13 +19,20 @@ public abstract class PKM
|
||||
public byte[] DecryptedPartyData => Write().Take(SIZE_PARTY).ToArray();
|
||||
public byte[] DecryptedBoxData => Write().Take(SIZE_STORED).ToArray();
|
||||
|
||||
public ushort CalculateChecksum()
|
||||
protected ushort CalculateChecksum()
|
||||
{
|
||||
ushort chk = 0;
|
||||
for (int i = 8; i < SIZE_STORED; i += 2) // Loop through the entire PK5
|
||||
chk += BitConverter.ToUInt16(Data, i);
|
||||
|
||||
return chk;
|
||||
switch (Format)
|
||||
{
|
||||
case 3:
|
||||
for (int i = 32; i < SIZE_STORED; i += 2)
|
||||
chk += BitConverter.ToUInt16(Data, i);
|
||||
return chk;
|
||||
default: // 4+
|
||||
for (int i = 8; i < SIZE_STORED; i += 2)
|
||||
chk += BitConverter.ToUInt16(Data, i);
|
||||
return chk;
|
||||
}
|
||||
}
|
||||
public abstract byte[] Encrypt();
|
||||
public abstract int Format { get; }
|
||||
|
||||
88
PKM/PKX.cs
88
PKM/PKX.cs
@@ -176,6 +176,11 @@ internal static string getSpeciesName(int species, int lang)
|
||||
try { return SpeciesLang[lang][species]; }
|
||||
catch { return ""; }
|
||||
}
|
||||
internal static bool getIsNicknamed(int species, string nick)
|
||||
{
|
||||
try { return SpeciesLang.All(list => list[species].ToUpper() != nick); }
|
||||
catch { return false; }
|
||||
}
|
||||
internal static readonly PersonalInfo[] Personal = Legal.PersonalAO;
|
||||
|
||||
// Stat Fetching
|
||||
@@ -1628,7 +1633,7 @@ internal static int getGender(int species, uint PID)
|
||||
new byte[] {0x1a, 0x1a}, // 381
|
||||
new byte[] {0x02, 0x02}, // 382
|
||||
new byte[] {0x46, 0x46}, // 383
|
||||
new byte[] {0x4c, 0x4c}, // 384
|
||||
new byte[] {0x4d, 0x4d}, // 384
|
||||
new byte[] {0x20, 0x20}, // 385
|
||||
new byte[] {0x2e, 0x2e}, // 386
|
||||
};
|
||||
@@ -2039,5 +2044,86 @@ internal static int getGender(int species, uint PID)
|
||||
new byte[] { }, // Unused
|
||||
new byte[] { 0x74, 0x20, 0x0D, 0x02, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xA1, 0x0C, 0x02, 0xE0, 0xFF },
|
||||
};
|
||||
|
||||
internal static byte[] decryptArray3(byte[] ekm)
|
||||
{
|
||||
if (ekm.Length != SIZE_3PARTY && ekm.Length != SIZE_3STORED)
|
||||
return null;
|
||||
|
||||
uint PID = BitConverter.ToUInt32(ekm, 0);
|
||||
uint OID = BitConverter.ToUInt32(ekm, 4);
|
||||
uint seed = PID ^ OID;
|
||||
|
||||
byte[] xorkey = BitConverter.GetBytes(seed);
|
||||
for (int i = 32; i < 80; i++)
|
||||
ekm[i] ^= xorkey[i % 4];
|
||||
return shuffleArray3(ekm, PID%24);
|
||||
}
|
||||
internal static byte[] shuffleArray3(byte[] data, uint sv)
|
||||
{
|
||||
byte[] sdata = new byte[data.Length];
|
||||
Array.Copy(data, sdata, 32); // Copy unshuffled bytes
|
||||
|
||||
// Shuffle Away!
|
||||
for (int block = 0; block < 4; block++)
|
||||
Array.Copy(data, 32 + 12 * blockPosition[block][sv], sdata, 32 + 12 * block, 12);
|
||||
|
||||
// Fill the Battle Stats back
|
||||
if (data.Length > SIZE_3STORED)
|
||||
Array.Copy(data, SIZE_3STORED, sdata, SIZE_3STORED, data.Length - SIZE_3STORED);
|
||||
|
||||
return sdata;
|
||||
}
|
||||
internal static byte[] encryptArray3(byte[] pkm)
|
||||
{
|
||||
if (pkm.Length != SIZE_3PARTY && pkm.Length != SIZE_3STORED)
|
||||
return null;
|
||||
|
||||
uint PID = BitConverter.ToUInt32(pkm, 0);
|
||||
uint OID = BitConverter.ToUInt32(pkm, 4);
|
||||
uint seed = PID ^ OID;
|
||||
|
||||
byte[] ekm = shuffleArray3(pkm, blockPositionInvert[PID%24]);
|
||||
byte[] xorkey = BitConverter.GetBytes(seed);
|
||||
for (int i = 32; i < 80; i++)
|
||||
ekm[i] ^= xorkey[i % 4];
|
||||
return ekm;
|
||||
}
|
||||
|
||||
internal static ushort getG4Item(ushort g3val)
|
||||
{
|
||||
ushort[] arr =
|
||||
{
|
||||
0,1,2,3,4,5,6,7,8,9,
|
||||
10,11,12,17,18,19,20,21,22,23,
|
||||
24,25,26,27,28,29,30,31,32,33,
|
||||
34,35,36,37,38,39,40,41,42,65,
|
||||
66,67,68,69,43,44,70,71,72,73,
|
||||
74,75,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,45,46,47,48,49,50,51,
|
||||
52,53,0xFFFF,55,56,57,58,59,60,0xFFFF,
|
||||
63,64,0xFFFF,76,77,78,79,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,80,81,82,83,84,85,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,86,87,0xFFFF,88,89,90,91,
|
||||
92,93,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,149,150,151,152,153,154,155,
|
||||
156,157,158,159,160,161,162,163,164,165,
|
||||
166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,201,202,
|
||||
203,204,205,206,207,208,0xFFFF,0xFFFF,0xFFFF,213,
|
||||
214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,
|
||||
234,235,236,237,238,239,240,241,242,243,
|
||||
244,245,246,247,248,249,250,251,252,253,
|
||||
254,255,256,257,258,259,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,
|
||||
0xFFFF,0xFFFF,0xFFFF,0xFFFF,260,261,262,263,264,
|
||||
};
|
||||
if (g3val > arr.Length)
|
||||
return 0xFFFF;
|
||||
return arr[g3val];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
294
PKX/f1-Main.cs
294
PKX/f1-Main.cs
@@ -724,48 +724,38 @@ private void openSAV(byte[] input, string path)
|
||||
// Generational Interface
|
||||
byte[] extraBytes = new byte[1];
|
||||
Tip1.RemoveAll(); Tip2.RemoveAll(); Tip3.RemoveAll(); // TSV/PSV
|
||||
|
||||
CB_Country.Visible = CB_SubRegion.Visible = CB_3DSReg.Visible =
|
||||
Label_Country.Visible = Label_SubRegion.Visible = Label_3DSRegion.Visible = SAV.Generation >= 6;
|
||||
CB_Ability.Visible = TB_AbilityNumber.Visible = SAV.Generation >= 6;
|
||||
Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = SAV.Generation >= 6;
|
||||
GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_History.Visible = BTN_Ribbons.Visible = SAV.Generation >= 6;
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = SAV.Generation >= 6;
|
||||
|
||||
PB_MarkPentagon.Visible = SAV.Generation == 6;
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = SAV.Generation == 6;
|
||||
TB_GameSync.Visible = TB_Secure1.Visible = TB_Secure2.Visible = L_GameSync.Visible = L_Secure1.Visible = L_Secure2.Visible = SAV.Generation == 6;
|
||||
|
||||
CB_Form.Visible = Label_Form.Visible = CHK_AsEgg.Visible = GB_EggConditions.Visible =
|
||||
Label_MetDate.Visible = CAL_MetDate.Visible = PB_Mark5.Visible = PB_Mark6.Visible = SAV.Generation >= 4;
|
||||
|
||||
DEV_Ability.Enabled = DEV_Ability.Visible = SAV.Generation < 6 || HaX;
|
||||
TB_AbilityNumber.Visible = SAV.Generation >= 6 && !HaX;
|
||||
CB_Ability.Visible = SAV.Generation >= 6 && !HaX;
|
||||
|
||||
switch (SAV.Generation)
|
||||
{
|
||||
case 3:
|
||||
extraBytes = PK3.ExtraBytes;
|
||||
break;
|
||||
case 4:
|
||||
TB_GameSync.Visible = TB_Secure1.Visible = TB_Secure2.Visible = false;
|
||||
L_GameSync.Visible = L_Secure1.Visible = L_Secure2.Visible = false;
|
||||
CB_Country.Visible = CB_SubRegion.Visible = CB_3DSReg.Visible = false;
|
||||
Label_Country.Visible = Label_SubRegion.Visible = Label_3DSRegion.Visible = false;
|
||||
CB_Ability.Visible = TB_AbilityNumber.Visible = false;
|
||||
GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_History.Visible = BTN_Ribbons.Visible = false;
|
||||
Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = false;
|
||||
PB_MarkPentagon.Visible = false;
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = false;
|
||||
|
||||
DEV_Ability.Enabled = DEV_Ability.Visible = true;
|
||||
|
||||
extraBytes = PK4.ExtraBytes;
|
||||
break;
|
||||
case 5:
|
||||
TB_GameSync.Visible = TB_Secure1.Visible = TB_Secure2.Visible = false;
|
||||
L_GameSync.Visible = L_Secure1.Visible = L_Secure2.Visible = false;
|
||||
CB_Country.Visible = CB_SubRegion.Visible = CB_3DSReg.Visible = false;
|
||||
Label_Country.Visible = Label_SubRegion.Visible = Label_3DSRegion.Visible = false;
|
||||
CB_Ability.Visible = TB_AbilityNumber.Visible = false;
|
||||
GB_nOT.Visible = GB_RelearnMoves.Visible = BTN_History.Visible = BTN_Ribbons.Visible = false;
|
||||
Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = false;
|
||||
PB_MarkPentagon.Visible = false;
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = false;
|
||||
|
||||
DEV_Ability.Enabled = DEV_Ability.Visible = true;
|
||||
extraBytes = PK5.ExtraBytes;
|
||||
break;
|
||||
case 6:
|
||||
TB_GameSync.Visible = TB_Secure1.Visible = TB_Secure2.Visible = true;
|
||||
L_GameSync.Visible = L_Secure1.Visible = L_Secure2.Visible = true;
|
||||
CB_Country.Visible = CB_SubRegion.Visible = CB_3DSReg.Visible = true;
|
||||
Label_Country.Visible = Label_SubRegion.Visible = Label_3DSRegion.Visible = true;
|
||||
DEV_Ability.Enabled = DEV_Ability.Visible = TB_AbilityNumber.Visible = HaX;
|
||||
GB_nOT.Visible = BTN_History.Visible = true;
|
||||
Label_EncryptionConstant.Visible = BTN_RerollEC.Visible = TB_EC.Visible = true;
|
||||
PB_MarkPentagon.Visible = true;
|
||||
PB_Legal.Visible = PB_WarnMove1.Visible = PB_WarnMove2.Visible = PB_WarnMove3.Visible = PB_WarnMove4.Visible = true;
|
||||
|
||||
CB_Ability.Visible = !HaX;
|
||||
extraBytes = PK6.ExtraBytes;
|
||||
TB_GameSync.Enabled = (SAV as SAV6).GameSyncID != 0;
|
||||
TB_GameSync.Text = (SAV as SAV6).GameSyncID.ToString("X16");
|
||||
@@ -1017,7 +1007,7 @@ private void populateFilteredDataSources()
|
||||
CB_Ball.DataSource = new BindingSource(BallDataSource.Where(b => b.Value <= SAV.MaxBallID), null);
|
||||
CB_Species.DataSource = new BindingSource(SpeciesDataSource.Where(s => s.Value <= SAV.MaxSpeciesID), null);
|
||||
DEV_Ability.DataSource = new BindingSource(AbilityDataSource.Where(a => a.Value <= SAV.MaxAbilityID), null);
|
||||
CB_GameOrigin.DataSource = new BindingSource(VersionDataSource.Where(g => g.Value <= SAV.MaxGameID), null);
|
||||
CB_GameOrigin.DataSource = new BindingSource(VersionDataSource.Where(g => g.Value <= SAV.MaxGameID || SAV.Generation >= 3 && g.Value == 15), null);
|
||||
|
||||
// Set the Move ComboBoxes too..
|
||||
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4, CB_RelearnMove1, CB_RelearnMove2, CB_RelearnMove3, CB_RelearnMove4 })
|
||||
@@ -1040,6 +1030,9 @@ public void populateFields(PKM pk, bool focus = true)
|
||||
Util.Alert("PKX File has an invalid checksum.");
|
||||
switch (pkm.Format)
|
||||
{
|
||||
case 3:
|
||||
populateFieldsPK3(pkm as PK3);
|
||||
break;
|
||||
case 4:
|
||||
populateFieldsPK4(pkm as PK4);
|
||||
break;
|
||||
@@ -1077,6 +1070,97 @@ public void populateFields(PKM pk, bool focus = true)
|
||||
dragout.Image = pk.Sprite;
|
||||
updateLegality();
|
||||
}
|
||||
private void populateFieldsPK3(PK3 pk3)
|
||||
{
|
||||
// Do first
|
||||
pk3.Stat_Level = PKX.getLevel(pk3.Species, pk3.EXP);
|
||||
if (pk3.Stat_Level == 100)
|
||||
pk3.EXP = PKX.getEXP(pk3.Stat_Level, pk3.Species);
|
||||
|
||||
CB_Species.SelectedValue = pk3.Species;
|
||||
TB_Level.Text = pk3.Stat_Level.ToString();
|
||||
TB_EXP.Text = pk3.EXP.ToString();
|
||||
|
||||
// Load rest
|
||||
CHK_Fateful.Checked = pk3.FatefulEncounter;
|
||||
CHK_IsEgg.Checked = pk3.IsEgg;
|
||||
CHK_Nicknamed.Checked = pk3.IsNicknamed;
|
||||
Label_OTGender.Text = gendersymbols[pk3.OT_Gender];
|
||||
Label_OTGender.ForeColor = pk3.OT_Gender == 1 ? Color.Red : Color.Blue;
|
||||
TB_PID.Text = pk3.PID.ToString("X8");
|
||||
CB_HeldItem.SelectedValue = pk3.HeldItem;
|
||||
setAbilityList(TB_AbilityNumber, pk3.Species, CB_Ability, CB_Form);
|
||||
DEV_Ability.SelectedValue = pk3.Ability;
|
||||
CB_Nature.SelectedValue = pk3.Nature;
|
||||
TB_TID.Text = pk3.TID.ToString("00000");
|
||||
TB_SID.Text = pk3.SID.ToString("00000");
|
||||
TB_Nickname.Text = pk3.Nickname;
|
||||
TB_OT.Text = pk3.OT_Name;
|
||||
TB_Friendship.Text = pk3.CurrentFriendship.ToString();
|
||||
GB_OT.BackgroundImage = null;
|
||||
CB_Language.SelectedValue = pk3.Language;
|
||||
CB_GameOrigin.SelectedValue = pk3.Version;
|
||||
CB_EncounterType.SelectedValue = pk3.Gen4 ? pk3.EncounterType : 0;
|
||||
CB_Ball.SelectedValue = pk3.Ball;
|
||||
|
||||
CB_MetLocation.SelectedValue = pk3.Met_Location;
|
||||
|
||||
TB_MetLevel.Text = pk3.Met_Level.ToString();
|
||||
|
||||
// Reset Label and ComboBox visibility, as well as non-data checked status.
|
||||
Label_PKRS.Visible = CB_PKRSStrain.Visible = CHK_Infected.Checked = pk3.PKRS_Strain != 0;
|
||||
Label_PKRSdays.Visible = CB_PKRSDays.Visible = pk3.PKRS_Days != 0;
|
||||
|
||||
// Set SelectedIndexes for PKRS
|
||||
CB_PKRSStrain.SelectedIndex = pk3.PKRS_Strain;
|
||||
CHK_Cured.Checked = pk3.PKRS_Strain > 0 && pk3.PKRS_Days == 0;
|
||||
CB_PKRSDays.SelectedIndex = Math.Min(CB_PKRSDays.Items.Count - 1, pk3.PKRS_Days); // to strip out bad hacked 'rus
|
||||
|
||||
TB_Cool.Text = pk3.CNT_Cool.ToString();
|
||||
TB_Beauty.Text = pk3.CNT_Beauty.ToString();
|
||||
TB_Cute.Text = pk3.CNT_Cute.ToString();
|
||||
TB_Smart.Text = pk3.CNT_Smart.ToString();
|
||||
TB_Tough.Text = pk3.CNT_Tough.ToString();
|
||||
TB_Sheen.Text = pk3.CNT_Sheen.ToString();
|
||||
|
||||
TB_HPIV.Text = pk3.IV_HP.ToString();
|
||||
TB_ATKIV.Text = pk3.IV_ATK.ToString();
|
||||
TB_DEFIV.Text = pk3.IV_DEF.ToString();
|
||||
TB_SPEIV.Text = pk3.IV_SPE.ToString();
|
||||
TB_SPAIV.Text = pk3.IV_SPA.ToString();
|
||||
TB_SPDIV.Text = pk3.IV_SPD.ToString();
|
||||
CB_HPType.SelectedValue = pk3.HPType;
|
||||
|
||||
TB_HPEV.Text = pk3.EV_HP.ToString();
|
||||
TB_ATKEV.Text = pk3.EV_ATK.ToString();
|
||||
TB_DEFEV.Text = pk3.EV_DEF.ToString();
|
||||
TB_SPEEV.Text = pk3.EV_SPE.ToString();
|
||||
TB_SPAEV.Text = pk3.EV_SPA.ToString();
|
||||
TB_SPDEV.Text = pk3.EV_SPD.ToString();
|
||||
|
||||
CB_Move1.SelectedValue = pk3.Move1;
|
||||
CB_Move2.SelectedValue = pk3.Move2;
|
||||
CB_Move3.SelectedValue = pk3.Move3;
|
||||
CB_Move4.SelectedValue = pk3.Move4;
|
||||
CB_PPu1.SelectedIndex = pk3.Move1_PPUps;
|
||||
CB_PPu2.SelectedIndex = pk3.Move2_PPUps;
|
||||
CB_PPu3.SelectedIndex = pk3.Move3_PPUps;
|
||||
CB_PPu4.SelectedIndex = pk3.Move4_PPUps;
|
||||
TB_PP1.Text = pk3.Move1_PP.ToString();
|
||||
TB_PP2.Text = pk3.Move2_PP.ToString();
|
||||
TB_PP3.Text = pk3.Move3_PP.ToString();
|
||||
TB_PP4.Text = pk3.Move4_PP.ToString();
|
||||
|
||||
// Load Extrabyte Value
|
||||
TB_ExtraByte.Text = pk3.Data[Convert.ToInt32(CB_ExtraBytes.Text, 16)].ToString();
|
||||
|
||||
updateStats();
|
||||
setIsShiny();
|
||||
|
||||
TB_EXP.Text = pk3.EXP.ToString();
|
||||
Label_Gender.Text = gendersymbols[pk3.Gender];
|
||||
Label_Gender.ForeColor = pk3.Gender == 2 ? Label_Species.ForeColor : (pk3.Gender == 1 ? Color.Red : Color.Blue);
|
||||
}
|
||||
private void populateFieldsPK4(PK4 pk4)
|
||||
{
|
||||
// Do first
|
||||
@@ -1493,6 +1577,27 @@ internal static void setAbilityList(MaskedTextBox tb_abil, int species, ComboBox
|
||||
|
||||
cb_abil.SelectedIndex = newabil < 3 ? newabil : 0;
|
||||
}
|
||||
private void setAbilityList3(MaskedTextBox tb_abil, int species, ComboBox cb_abil, ComboBox cb_forme)
|
||||
{
|
||||
if (!fieldsInitialized && string.IsNullOrWhiteSpace(tb_abil.Text))
|
||||
return;
|
||||
int newabil = Convert.ToInt16(tb_abil.Text) >> 1;
|
||||
|
||||
int form = cb_forme.SelectedIndex;
|
||||
byte[] abils = PKX.Gen3Abilities[Util.getIndex(CB_Species)];
|
||||
if (abils[0] == 76) abils[0] = 77; // Air Lock +1
|
||||
if (abils[1] == 76) abils[1] = 77; // Air Lock +1
|
||||
|
||||
// Build Ability List
|
||||
List<string> ability_list = new List<string>
|
||||
{
|
||||
abilitylist[abils[0]] + " (1)",
|
||||
abilitylist[abils[1]] + " (2)",
|
||||
};
|
||||
cb_abil.DataSource = ability_list;
|
||||
|
||||
cb_abil.SelectedIndex = newabil < 3 ? newabil : 0;
|
||||
}
|
||||
// PKX Data Calculation Functions //
|
||||
private void setIsShiny()
|
||||
{
|
||||
@@ -1789,7 +1894,10 @@ private void updateIVs(object sender, EventArgs e)
|
||||
|
||||
TB_IVTotal.Text = pkm.IVs.Sum().ToString();
|
||||
|
||||
L_Characteristic.Text = characteristics[pkm.Characteristic];
|
||||
int characteristic = pkm.Characteristic;
|
||||
L_Characteristic.Visible = characteristic > -1;
|
||||
if (characteristic > -1)
|
||||
L_Characteristic.Text = characteristics[pkm.Characteristic];
|
||||
updateStats();
|
||||
}
|
||||
private void updateEVs(object sender, EventArgs e)
|
||||
@@ -2232,27 +2340,26 @@ private void updateNatureModification(object sender, EventArgs e)
|
||||
private void updateNickname(object sender, EventArgs e)
|
||||
{
|
||||
if (fieldsInitialized && ModifierKeys == Keys.Control && sender != null) // Import Showdown
|
||||
{
|
||||
clickShowdownImportPK6(sender, e);
|
||||
return;
|
||||
}
|
||||
{ clickShowdownImportPK6(sender, e); return; }
|
||||
if (fieldsInitialized && ModifierKeys == Keys.Alt && sender != null) // Export Showdown
|
||||
{
|
||||
clickShowdownExportPK6(sender, e);
|
||||
return;
|
||||
}
|
||||
if (!fieldsInitialized || CHK_Nicknamed.Checked) return;
|
||||
{ clickShowdownExportPK6(sender, e); return; }
|
||||
if (!fieldsInitialized || CHK_Nicknamed.Checked)
|
||||
return;
|
||||
|
||||
// Fetch Current Species and set it as Nickname Text
|
||||
int species = Util.getIndex(CB_Species);
|
||||
if (species == 0 || species > 721)
|
||||
if (species < 1 || species > SAV.MaxSpeciesID)
|
||||
TB_Nickname.Text = "";
|
||||
else
|
||||
{
|
||||
// get language
|
||||
int lang = Util.getIndex(CB_Language);
|
||||
if (CHK_IsEgg.Checked) species = 0; // Set species to 0 to get the egg name.
|
||||
TB_Nickname.Text = PKX.getSpeciesName(CHK_IsEgg.Checked ? 0 : species, lang);
|
||||
string nick = PKX.getSpeciesName(CHK_IsEgg.Checked ? 0 : species, lang);
|
||||
|
||||
if (SAV.Generation < 5) // All caps GenIV and previous
|
||||
nick = nick.ToUpper();
|
||||
TB_Nickname.Text = nick;
|
||||
}
|
||||
}
|
||||
private void updateNicknameClick(object sender, MouseEventArgs e)
|
||||
@@ -2666,6 +2773,9 @@ public PKM preparePKM(bool click = true)
|
||||
PKM pk = null;
|
||||
switch (pkm.Format)
|
||||
{
|
||||
case 3:
|
||||
pk = preparePK3();
|
||||
break;
|
||||
case 4:
|
||||
pk = preparePK4();
|
||||
break;
|
||||
@@ -2678,6 +2788,95 @@ public PKM preparePKM(bool click = true)
|
||||
}
|
||||
return pk?.Clone();
|
||||
}
|
||||
private PK3 preparePK3()
|
||||
{
|
||||
PK3 pk3 = pkm as PK3;
|
||||
if (pk3 == null)
|
||||
return null;
|
||||
|
||||
pk3.Species = Util.getIndex(CB_Species);
|
||||
pk3.G3Item = Util.getIndex(CB_HeldItem);
|
||||
pk3.TID = Util.ToInt32(TB_TID.Text);
|
||||
pk3.SID = Util.ToInt32(TB_SID.Text);
|
||||
pk3.EXP = Util.ToUInt32(TB_EXP.Text);
|
||||
pk3.PID = Util.getHEXval(TB_PID.Text);
|
||||
pk3.Ability = (byte)Util.getIndex(DEV_Ability);
|
||||
//pk4.Ability = (byte)Array.IndexOf(abilitylist, CB_Ability.Text.Remove(CB_Ability.Text.Length - 4));
|
||||
|
||||
pk3.FatefulEncounter = CHK_Fateful.Checked;
|
||||
pk3.Gender = PKX.getGender(Label_Gender.Text);
|
||||
pk3.EV_HP = Util.ToInt32(TB_HPEV.Text);
|
||||
pk3.EV_ATK = Util.ToInt32(TB_ATKEV.Text);
|
||||
pk3.EV_DEF = Util.ToInt32(TB_DEFEV.Text);
|
||||
pk3.EV_SPE = Util.ToInt32(TB_SPEEV.Text);
|
||||
pk3.EV_SPA = Util.ToInt32(TB_SPAEV.Text);
|
||||
pk3.EV_SPD = Util.ToInt32(TB_SPDEV.Text);
|
||||
|
||||
pk3.CNT_Cool = Util.ToInt32(TB_Cool.Text);
|
||||
pk3.CNT_Beauty = Util.ToInt32(TB_Beauty.Text);
|
||||
pk3.CNT_Cute = Util.ToInt32(TB_Cute.Text);
|
||||
pk3.CNT_Smart = Util.ToInt32(TB_Smart.Text);
|
||||
pk3.CNT_Tough = Util.ToInt32(TB_Tough.Text);
|
||||
pk3.CNT_Sheen = Util.ToInt32(TB_Sheen.Text);
|
||||
|
||||
pk3.PKRS_Days = CB_PKRSDays.SelectedIndex;
|
||||
pk3.PKRS_Strain = CB_PKRSStrain.SelectedIndex;
|
||||
pk3.Nickname = TB_Nickname.Text;
|
||||
pk3.Move1 = Util.getIndex(CB_Move1);
|
||||
pk3.Move2 = Util.getIndex(CB_Move2);
|
||||
pk3.Move3 = Util.getIndex(CB_Move3);
|
||||
pk3.Move4 = Util.getIndex(CB_Move4);
|
||||
pk3.Move1_PP = Util.getIndex(CB_Move1) > 0 ? Util.ToInt32(TB_PP1.Text) : 0;
|
||||
pk3.Move2_PP = Util.getIndex(CB_Move2) > 0 ? Util.ToInt32(TB_PP2.Text) : 0;
|
||||
pk3.Move3_PP = Util.getIndex(CB_Move3) > 0 ? Util.ToInt32(TB_PP3.Text) : 0;
|
||||
pk3.Move4_PP = Util.getIndex(CB_Move4) > 0 ? Util.ToInt32(TB_PP4.Text) : 0;
|
||||
pk3.Move1_PPUps = Util.getIndex(CB_Move1) > 0 ? CB_PPu1.SelectedIndex : 0;
|
||||
pk3.Move2_PPUps = Util.getIndex(CB_Move2) > 0 ? CB_PPu2.SelectedIndex : 0;
|
||||
pk3.Move3_PPUps = Util.getIndex(CB_Move3) > 0 ? CB_PPu3.SelectedIndex : 0;
|
||||
pk3.Move4_PPUps = Util.getIndex(CB_Move4) > 0 ? CB_PPu4.SelectedIndex : 0;
|
||||
|
||||
pk3.IV_HP = Util.ToInt32(TB_HPIV.Text);
|
||||
pk3.IV_ATK = Util.ToInt32(TB_ATKIV.Text);
|
||||
pk3.IV_DEF = Util.ToInt32(TB_DEFIV.Text);
|
||||
pk3.IV_SPE = Util.ToInt32(TB_SPEIV.Text);
|
||||
pk3.IV_SPA = Util.ToInt32(TB_SPAIV.Text);
|
||||
pk3.IV_SPD = Util.ToInt32(TB_SPDIV.Text);
|
||||
pk3.IsEgg = CHK_IsEgg.Checked;
|
||||
pk3.IsNicknamed = CHK_Nicknamed.Checked;
|
||||
|
||||
pk3.OT_Name = TB_OT.Text;
|
||||
pk3.CurrentFriendship = Util.ToInt32(TB_Friendship.Text);
|
||||
|
||||
pk3.Ball = Util.getIndex(CB_Ball);
|
||||
pk3.Met_Level = Util.ToInt32(TB_MetLevel.Text);
|
||||
pk3.OT_Gender = PKX.getGender(Label_OTGender.Text);
|
||||
pk3.Version = Util.getIndex(CB_GameOrigin);
|
||||
pk3.Language = Util.getIndex(CB_Language);
|
||||
|
||||
pk3.Met_Location = Util.getIndex(CB_MetLocation);
|
||||
|
||||
// Toss in Party Stats
|
||||
Array.Resize(ref pk3.Data, pk3.SIZE_PARTY);
|
||||
pk3.Stat_Level = Util.ToInt32(TB_Level.Text);
|
||||
pk3.Stat_HPCurrent = Util.ToInt32(Stat_HP.Text);
|
||||
pk3.Stat_HPMax = Util.ToInt32(Stat_HP.Text);
|
||||
pk3.Stat_ATK = Util.ToInt32(Stat_ATK.Text);
|
||||
pk3.Stat_DEF = Util.ToInt32(Stat_DEF.Text);
|
||||
pk3.Stat_SPE = Util.ToInt32(Stat_SPE.Text);
|
||||
pk3.Stat_SPA = Util.ToInt32(Stat_SPA.Text);
|
||||
pk3.Stat_SPD = Util.ToInt32(Stat_SPD.Text);
|
||||
|
||||
if (HaX)
|
||||
{
|
||||
pk3.Stat_Level = (byte)Math.Min(Convert.ToInt32(MT_Level.Text), byte.MaxValue);
|
||||
}
|
||||
|
||||
// Fix Moves if a slot is empty
|
||||
pk3.FixMoves();
|
||||
|
||||
pk3.RefreshChecksum();
|
||||
return pk3;
|
||||
}
|
||||
private PK4 preparePK4()
|
||||
{
|
||||
PK4 pk4 = pkm as PK4;
|
||||
@@ -2692,8 +2891,7 @@ private PK4 preparePK4()
|
||||
pk4.PID = Util.getHEXval(TB_PID.Text);
|
||||
pk4.Ability = (byte)Util.getIndex(DEV_Ability);
|
||||
//pk4.Ability = (byte)Array.IndexOf(abilitylist, CB_Ability.Text.Remove(CB_Ability.Text.Length - 4));
|
||||
|
||||
pk4.Nature = (byte)Util.getIndex(CB_Nature);
|
||||
|
||||
pk4.FatefulEncounter = CHK_Fateful.Checked;
|
||||
pk4.Gender = PKX.getGender(Label_Gender.Text);
|
||||
pk4.AltForm = (MT_Form.Enabled ? Convert.ToInt32(MT_Form.Text) : CB_Form.SelectedIndex) & 0x1F;
|
||||
|
||||
181
SAV/SAV_SimpleTrainer.Designer.cs
generated
181
SAV/SAV_SimpleTrainer.Designer.cs
generated
@@ -28,11 +28,11 @@ protected override void Dispose(bool disposing)
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.GB_Adventure = new System.Windows.Forms.GroupBox();
|
||||
this.L_Started = new System.Windows.Forms.Label();
|
||||
this.CAL_AdventureStartDate = new System.Windows.Forms.DateTimePicker();
|
||||
this.CAL_HoFDate = new System.Windows.Forms.DateTimePicker();
|
||||
this.L_LastSaved = new System.Windows.Forms.Label();
|
||||
this.L_Fame = new System.Windows.Forms.Label();
|
||||
this.MT_Seconds = new System.Windows.Forms.MaskedTextBox();
|
||||
this.MT_Hours = new System.Windows.Forms.MaskedTextBox();
|
||||
this.L_Seconds = new System.Windows.Forms.Label();
|
||||
@@ -62,8 +62,8 @@ private void InitializeComponent()
|
||||
this.L_X = new System.Windows.Forms.Label();
|
||||
this.B_Save = new System.Windows.Forms.Button();
|
||||
this.B_Cancel = new System.Windows.Forms.Button();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.GB_Trainer = new System.Windows.Forms.GroupBox();
|
||||
this.GB_Badges = new System.Windows.Forms.GroupBox();
|
||||
this.CHK_H8 = new System.Windows.Forms.CheckBox();
|
||||
this.CHK_H7 = new System.Windows.Forms.CheckBox();
|
||||
this.CHK_H6 = new System.Windows.Forms.CheckBox();
|
||||
@@ -80,36 +80,36 @@ 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.groupBox2.SuspendLayout();
|
||||
this.GB_Adventure.SuspendLayout();
|
||||
this.GB_Map.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_Z)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_M)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_Y)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_X)).BeginInit();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.GB_Trainer.SuspendLayout();
|
||||
this.GB_Badges.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// groupBox2
|
||||
// GB_Adventure
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.L_Started);
|
||||
this.groupBox2.Controls.Add(this.CAL_AdventureStartDate);
|
||||
this.groupBox2.Controls.Add(this.CAL_HoFDate);
|
||||
this.groupBox2.Controls.Add(this.L_LastSaved);
|
||||
this.groupBox2.Controls.Add(this.MT_Seconds);
|
||||
this.groupBox2.Controls.Add(this.MT_Hours);
|
||||
this.groupBox2.Controls.Add(this.L_Seconds);
|
||||
this.groupBox2.Controls.Add(this.L_Hours);
|
||||
this.groupBox2.Controls.Add(this.MT_Minutes);
|
||||
this.groupBox2.Controls.Add(this.L_Minutes);
|
||||
this.groupBox2.Controls.Add(this.CAL_AdventureStartTime);
|
||||
this.groupBox2.Controls.Add(this.CAL_HoFTime);
|
||||
this.groupBox2.Location = new System.Drawing.Point(12, 98);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(200, 151);
|
||||
this.groupBox2.TabIndex = 70;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Adventure Info";
|
||||
this.GB_Adventure.Controls.Add(this.L_Started);
|
||||
this.GB_Adventure.Controls.Add(this.CAL_AdventureStartDate);
|
||||
this.GB_Adventure.Controls.Add(this.CAL_HoFDate);
|
||||
this.GB_Adventure.Controls.Add(this.L_Fame);
|
||||
this.GB_Adventure.Controls.Add(this.MT_Seconds);
|
||||
this.GB_Adventure.Controls.Add(this.MT_Hours);
|
||||
this.GB_Adventure.Controls.Add(this.L_Seconds);
|
||||
this.GB_Adventure.Controls.Add(this.L_Hours);
|
||||
this.GB_Adventure.Controls.Add(this.MT_Minutes);
|
||||
this.GB_Adventure.Controls.Add(this.L_Minutes);
|
||||
this.GB_Adventure.Controls.Add(this.CAL_AdventureStartTime);
|
||||
this.GB_Adventure.Controls.Add(this.CAL_HoFTime);
|
||||
this.GB_Adventure.Location = new System.Drawing.Point(11, 98);
|
||||
this.GB_Adventure.Name = "GB_Adventure";
|
||||
this.GB_Adventure.Size = new System.Drawing.Size(200, 151);
|
||||
this.GB_Adventure.TabIndex = 70;
|
||||
this.GB_Adventure.TabStop = false;
|
||||
this.GB_Adventure.Text = "Adventure Info";
|
||||
//
|
||||
// L_Started
|
||||
//
|
||||
@@ -141,14 +141,14 @@ private void InitializeComponent()
|
||||
this.CAL_HoFDate.TabIndex = 31;
|
||||
this.CAL_HoFDate.Value = new System.DateTime(2000, 1, 1, 0, 0, 0, 0);
|
||||
//
|
||||
// L_LastSaved
|
||||
// L_Fame
|
||||
//
|
||||
this.L_LastSaved.Location = new System.Drawing.Point(4, 107);
|
||||
this.L_LastSaved.Name = "L_LastSaved";
|
||||
this.L_LastSaved.Size = new System.Drawing.Size(80, 20);
|
||||
this.L_LastSaved.TabIndex = 32;
|
||||
this.L_LastSaved.Text = "Hall of Fame:";
|
||||
this.L_LastSaved.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
this.L_Fame.Location = new System.Drawing.Point(4, 107);
|
||||
this.L_Fame.Name = "L_Fame";
|
||||
this.L_Fame.Size = new System.Drawing.Size(80, 20);
|
||||
this.L_Fame.TabIndex = 32;
|
||||
this.L_Fame.Text = "Hall of Fame:";
|
||||
this.L_Fame.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
|
||||
//
|
||||
// MT_Seconds
|
||||
//
|
||||
@@ -340,7 +340,7 @@ private void InitializeComponent()
|
||||
this.GB_Map.Controls.Add(this.L_CurrentMap);
|
||||
this.GB_Map.Controls.Add(this.L_Z);
|
||||
this.GB_Map.Controls.Add(this.L_X);
|
||||
this.GB_Map.Location = new System.Drawing.Point(218, 100);
|
||||
this.GB_Map.Location = new System.Drawing.Point(217, 100);
|
||||
this.GB_Map.Name = "GB_Map";
|
||||
this.GB_Map.Size = new System.Drawing.Size(157, 125);
|
||||
this.GB_Map.TabIndex = 71;
|
||||
@@ -438,7 +438,7 @@ private void InitializeComponent()
|
||||
//
|
||||
// B_Save
|
||||
//
|
||||
this.B_Save.Location = new System.Drawing.Point(300, 226);
|
||||
this.B_Save.Location = new System.Drawing.Point(299, 226);
|
||||
this.B_Save.Name = "B_Save";
|
||||
this.B_Save.Size = new System.Drawing.Size(75, 23);
|
||||
this.B_Save.TabIndex = 73;
|
||||
@@ -448,7 +448,7 @@ private void InitializeComponent()
|
||||
//
|
||||
// B_Cancel
|
||||
//
|
||||
this.B_Cancel.Location = new System.Drawing.Point(219, 226);
|
||||
this.B_Cancel.Location = new System.Drawing.Point(218, 226);
|
||||
this.B_Cancel.Name = "B_Cancel";
|
||||
this.B_Cancel.Size = new System.Drawing.Size(75, 23);
|
||||
this.B_Cancel.TabIndex = 72;
|
||||
@@ -456,49 +456,49 @@ private void InitializeComponent()
|
||||
this.B_Cancel.UseVisualStyleBackColor = true;
|
||||
this.B_Cancel.Click += new System.EventHandler(this.B_Cancel_Click);
|
||||
//
|
||||
// groupBox1
|
||||
// GB_Trainer
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.TB_OTName);
|
||||
this.groupBox1.Controls.Add(this.B_MaxCash);
|
||||
this.groupBox1.Controls.Add(this.MT_SID);
|
||||
this.groupBox1.Controls.Add(this.MT_TID);
|
||||
this.groupBox1.Controls.Add(this.L_Money);
|
||||
this.groupBox1.Controls.Add(this.L_SID);
|
||||
this.groupBox1.Controls.Add(this.CB_Gender);
|
||||
this.groupBox1.Controls.Add(this.MT_Money);
|
||||
this.groupBox1.Controls.Add(this.L_TID);
|
||||
this.groupBox1.Controls.Add(this.L_TrainerName);
|
||||
this.groupBox1.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Size = new System.Drawing.Size(200, 82);
|
||||
this.groupBox1.TabIndex = 74;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "Trainer";
|
||||
this.GB_Trainer.Controls.Add(this.TB_OTName);
|
||||
this.GB_Trainer.Controls.Add(this.B_MaxCash);
|
||||
this.GB_Trainer.Controls.Add(this.MT_SID);
|
||||
this.GB_Trainer.Controls.Add(this.MT_TID);
|
||||
this.GB_Trainer.Controls.Add(this.L_Money);
|
||||
this.GB_Trainer.Controls.Add(this.L_SID);
|
||||
this.GB_Trainer.Controls.Add(this.CB_Gender);
|
||||
this.GB_Trainer.Controls.Add(this.MT_Money);
|
||||
this.GB_Trainer.Controls.Add(this.L_TID);
|
||||
this.GB_Trainer.Controls.Add(this.L_TrainerName);
|
||||
this.GB_Trainer.Location = new System.Drawing.Point(11, 12);
|
||||
this.GB_Trainer.Name = "GB_Trainer";
|
||||
this.GB_Trainer.Size = new System.Drawing.Size(200, 82);
|
||||
this.GB_Trainer.TabIndex = 74;
|
||||
this.GB_Trainer.TabStop = false;
|
||||
this.GB_Trainer.Text = "Trainer";
|
||||
//
|
||||
// groupBox3
|
||||
// GB_Badges
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.CHK_H8);
|
||||
this.groupBox3.Controls.Add(this.CHK_H7);
|
||||
this.groupBox3.Controls.Add(this.CHK_H6);
|
||||
this.groupBox3.Controls.Add(this.CHK_H5);
|
||||
this.groupBox3.Controls.Add(this.CHK_H4);
|
||||
this.groupBox3.Controls.Add(this.CHK_H3);
|
||||
this.groupBox3.Controls.Add(this.CHK_H2);
|
||||
this.groupBox3.Controls.Add(this.CHK_H1);
|
||||
this.groupBox3.Controls.Add(this.CHK_8);
|
||||
this.groupBox3.Controls.Add(this.CHK_7);
|
||||
this.groupBox3.Controls.Add(this.CHK_6);
|
||||
this.groupBox3.Controls.Add(this.CHK_5);
|
||||
this.groupBox3.Controls.Add(this.CHK_4);
|
||||
this.groupBox3.Controls.Add(this.CHK_3);
|
||||
this.groupBox3.Controls.Add(this.CHK_2);
|
||||
this.groupBox3.Controls.Add(this.CHK_1);
|
||||
this.groupBox3.Location = new System.Drawing.Point(219, 12);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(157, 82);
|
||||
this.groupBox3.TabIndex = 75;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Badges";
|
||||
this.GB_Badges.Controls.Add(this.CHK_H8);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H7);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H6);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H5);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H4);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H3);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H2);
|
||||
this.GB_Badges.Controls.Add(this.CHK_H1);
|
||||
this.GB_Badges.Controls.Add(this.CHK_8);
|
||||
this.GB_Badges.Controls.Add(this.CHK_7);
|
||||
this.GB_Badges.Controls.Add(this.CHK_6);
|
||||
this.GB_Badges.Controls.Add(this.CHK_5);
|
||||
this.GB_Badges.Controls.Add(this.CHK_4);
|
||||
this.GB_Badges.Controls.Add(this.CHK_3);
|
||||
this.GB_Badges.Controls.Add(this.CHK_2);
|
||||
this.GB_Badges.Controls.Add(this.CHK_1);
|
||||
this.GB_Badges.Location = new System.Drawing.Point(218, 12);
|
||||
this.GB_Badges.Name = "GB_Badges";
|
||||
this.GB_Badges.Size = new System.Drawing.Size(157, 82);
|
||||
this.GB_Badges.TabIndex = 75;
|
||||
this.GB_Badges.TabStop = false;
|
||||
this.GB_Badges.Text = "Badges";
|
||||
//
|
||||
// CHK_H8
|
||||
//
|
||||
@@ -664,37 +664,38 @@ private void InitializeComponent()
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(386, 261);
|
||||
this.Controls.Add(this.groupBox3);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.ClientSize = new System.Drawing.Size(384, 261);
|
||||
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.groupBox2);
|
||||
this.Controls.Add(this.GB_Adventure);
|
||||
this.MinimumSize = new System.Drawing.Size(400, 300);
|
||||
this.Name = "SAV_SimpleTrainer";
|
||||
this.Text = "Trainer Data Editor";
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.GB_Adventure.ResumeLayout(false);
|
||||
this.GB_Adventure.PerformLayout();
|
||||
this.GB_Map.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_Z)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_M)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_Y)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.NUD_X)).EndInit();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox3.PerformLayout();
|
||||
this.GB_Trainer.ResumeLayout(false);
|
||||
this.GB_Trainer.PerformLayout();
|
||||
this.GB_Badges.ResumeLayout(false);
|
||||
this.GB_Badges.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.GroupBox GB_Adventure;
|
||||
private System.Windows.Forms.Label L_Started;
|
||||
private System.Windows.Forms.DateTimePicker CAL_AdventureStartDate;
|
||||
private System.Windows.Forms.DateTimePicker CAL_HoFDate;
|
||||
private System.Windows.Forms.Label L_LastSaved;
|
||||
private System.Windows.Forms.Label L_Fame;
|
||||
private System.Windows.Forms.MaskedTextBox MT_Seconds;
|
||||
private System.Windows.Forms.MaskedTextBox MT_Hours;
|
||||
private System.Windows.Forms.Label L_Seconds;
|
||||
@@ -724,8 +725,8 @@ private void InitializeComponent()
|
||||
private System.Windows.Forms.Label L_X;
|
||||
private System.Windows.Forms.Button B_Save;
|
||||
private System.Windows.Forms.Button B_Cancel;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.GroupBox GB_Trainer;
|
||||
private System.Windows.Forms.GroupBox GB_Badges;
|
||||
private System.Windows.Forms.CheckBox CHK_8;
|
||||
private System.Windows.Forms.CheckBox CHK_7;
|
||||
private System.Windows.Forms.CheckBox CHK_6;
|
||||
|
||||
@@ -20,6 +20,20 @@ public SAV_SimpleTrainer()
|
||||
MT_TID.Text = SAV.TID.ToString("00000");
|
||||
MT_SID.Text = SAV.SID.ToString("00000");
|
||||
MT_Money.Text = SAV.Money.ToString();
|
||||
MT_Hours.Text = SAV.PlayedHours.ToString();
|
||||
MT_Minutes.Text = SAV.PlayedMinutes.ToString();
|
||||
MT_Seconds.Text = SAV.PlayedSeconds.ToString();
|
||||
|
||||
if (SAV is SAV3)
|
||||
{
|
||||
GB_Map.Visible = false;
|
||||
GB_Badges.Visible = false; // todo
|
||||
|
||||
L_Started.Visible = L_Fame.Visible = false;
|
||||
CAL_AdventureStartDate.Visible = CAL_HoFDate.Visible = false;
|
||||
CAL_AdventureStartTime.Visible = CAL_HoFTime.Visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int badgeval = 0;
|
||||
if (SAV is SAV4)
|
||||
@@ -54,9 +68,6 @@ public SAV_SimpleTrainer()
|
||||
cba[i].Checked = (badgeval & 1 << i) != 0;
|
||||
}
|
||||
|
||||
MT_Hours.Text = SAV.PlayedHours.ToString();
|
||||
MT_Minutes.Text = SAV.PlayedMinutes.ToString();
|
||||
MT_Seconds.Text = SAV.PlayedSeconds.ToString();
|
||||
CAL_HoFDate.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToFame);
|
||||
CAL_HoFTime.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToFame % 86400);
|
||||
CAL_AdventureStartDate.Value = new DateTime(2000, 1, 1).AddSeconds(SAV.SecondsToStart);
|
||||
@@ -81,6 +92,10 @@ private void B_Save_Click(object sender, EventArgs e)
|
||||
SAV.SID = (ushort)Util.ToUInt32(MT_SID.Text);
|
||||
SAV.Money = Util.ToUInt32(MT_Money.Text);
|
||||
|
||||
SAV.PlayedHours = ushort.Parse(MT_Hours.Text);
|
||||
SAV.PlayedMinutes = ushort.Parse(MT_Minutes.Text) % 60;
|
||||
SAV.PlayedSeconds = ushort.Parse(MT_Seconds.Text) % 60;
|
||||
|
||||
// Copy Badges
|
||||
int badgeval = 0;
|
||||
for (int i = 0; i < cba.Length; i++)
|
||||
@@ -108,12 +123,7 @@ private void B_Save_Click(object sender, EventArgs e)
|
||||
s.Y = (int)NUD_Y.Value;
|
||||
s.Badges = badgeval & 0xFF;
|
||||
}
|
||||
|
||||
// Save PlayTime
|
||||
SAV.PlayedHours = ushort.Parse(MT_Hours.Text);
|
||||
SAV.PlayedMinutes = ushort.Parse(MT_Minutes.Text) % 60;
|
||||
SAV.PlayedSeconds = ushort.Parse(MT_Seconds.Text) % 60;
|
||||
|
||||
|
||||
SAV.SecondsToStart = getSeconds(CAL_AdventureStartDate, CAL_AdventureStartTime);
|
||||
SAV.SecondsToFame = getSeconds(CAL_HoFDate, CAL_HoFTime);
|
||||
|
||||
|
||||
382
Saves/SAV3.cs
Normal file
382
Saves/SAV3.cs
Normal file
@@ -0,0 +1,382 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX
|
||||
{
|
||||
public sealed class SAV3 : SaveFile
|
||||
{
|
||||
public override string BAKName => $"{FileName} [{OT} ({Version})" +/* - {LastSavedTime}*/ "].bak";
|
||||
public override string Filter => "Main SAV|*.*";
|
||||
public override string Extension => "";
|
||||
|
||||
/* SAV3 Structure:
|
||||
* 0xE000 per save file
|
||||
* 14 blocks @ 0x1000 each.
|
||||
* Blocks do not use all 0x1000 bytes allocated.
|
||||
* Via: http://bulbapedia.bulbagarden.net/wiki/Save_data_structure_in_Generation_III
|
||||
*/
|
||||
private readonly int[] chunkLength =
|
||||
{
|
||||
0xf2c, // 0 | Trainer info
|
||||
0xf80, // 1 | Team / items
|
||||
0xf80, // 2 | Unknown
|
||||
0xf80, // 3 | Unknown
|
||||
0xf08, // 4 | Rival info
|
||||
0xf80, // 5 | PC Block 0
|
||||
0xf80, // 6 | PC Block 1
|
||||
0xf80, // 7 | PC Block 2
|
||||
0xf80, // 8 | PC Block 3
|
||||
0xf80, // 9 | PC Block 4
|
||||
0xf80, // A | PC Block 5
|
||||
0xf80, // B | PC Block 6
|
||||
0xf80, // C | PC Block 7
|
||||
0x7d0 // D | PC Block 8
|
||||
};
|
||||
|
||||
public SAV3(byte[] data = null)
|
||||
{
|
||||
Data = data == null ? new byte[SaveUtil.SIZE_G3RAW] : (byte[])data.Clone();
|
||||
BAK = (byte[])Data.Clone();
|
||||
Exportable = !Data.SequenceEqual(new byte[Data.Length]);
|
||||
|
||||
BlockOrder = new int[14];
|
||||
ActiveSAV = SaveUtil.SIZE_G3RAWHALF == data.Length || BitConverter.ToUInt32(Data, 0xFFC) > BitConverter.ToUInt32(Data, 0xEFFC) ? 0 : 1;
|
||||
for (int i = 0; i < 14; i++)
|
||||
BlockOrder[i] = BitConverter.ToInt16(Data, ABO + i*0x1000 + 0xFF4);
|
||||
|
||||
// Detect RS/E/FRLG
|
||||
// Section 0 stores Game Code @ 0x00AC; 0 for RS, 1 for FRLG, else for Emerald
|
||||
Trainer1 = Array.IndexOf(BlockOrder, 0)*0x1000 + ABO;
|
||||
Party = Array.IndexOf(BlockOrder, 1)*0x1000 + ABO;
|
||||
Block2 = Array.IndexOf(BlockOrder, 2)*0x1000 + ABO;
|
||||
Block3 = Array.IndexOf(BlockOrder, 3)*0x1000 + ABO;
|
||||
|
||||
uint GameCode = BitConverter.ToUInt32(Data, ABO + Array.IndexOf(BlockOrder, 0)*0x1000);
|
||||
SaveVersion = GameCode < 2 ? (int)GameCode : 2;
|
||||
|
||||
// Set up PC data buffer beyond end of save file.
|
||||
Box = Data.Length;
|
||||
Array.Resize(ref Data, Data.Length + 0x10000); // More than enough empty space.
|
||||
|
||||
// Copy chunk to the allocated location
|
||||
for (int i = 5; i < 14; i++)
|
||||
{
|
||||
int blockIndex = Array.IndexOf(BlockOrder, i);
|
||||
if (blockIndex == -1) // block empty
|
||||
continue;
|
||||
Array.Copy(Data, blockIndex * 0x1000 + ABO, Data, Box + (i - 5)*0xF80, chunkLength[i]);
|
||||
}
|
||||
|
||||
HeldItems = Legal.HeldItems_RS;
|
||||
|
||||
if (!Exportable)
|
||||
resetBoxes();
|
||||
}
|
||||
|
||||
private readonly int SaveVersion;
|
||||
private readonly int ActiveSAV;
|
||||
private int ABO => ActiveSAV*0xE000;
|
||||
private readonly int[] BlockOrder;
|
||||
|
||||
// Configuration
|
||||
public override byte[] BAK { get; }
|
||||
public override bool Exportable { get; }
|
||||
public override SaveFile Clone() { return new SAV3(Data.Take(Box).ToArray()); }
|
||||
|
||||
public override int SIZE_STORED => PKX.SIZE_3STORED;
|
||||
public override int SIZE_PARTY => PKX.SIZE_3PARTY;
|
||||
public override PKM BlankPKM => new PK3();
|
||||
protected override Type PKMType => typeof(PK3);
|
||||
|
||||
public override int MaxMoveID => 354;
|
||||
public override int MaxSpeciesID => 386;
|
||||
public override int MaxAbilityID => 77;
|
||||
public override int MaxItemID => 374;
|
||||
public override int MaxBallID => 0xC;
|
||||
public override int MaxGameID => 5;
|
||||
|
||||
public override int BoxCount => 14;
|
||||
public override int MaxEV => 252;
|
||||
public override int Generation => 3;
|
||||
protected override int GiftCountMax => 1;
|
||||
public override int OTLength => 8;
|
||||
public override int NickLength => 10;
|
||||
|
||||
private int Block2, Block3;
|
||||
|
||||
// Checksums
|
||||
protected override void setChecksums()
|
||||
{
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
byte[] chunk = Data.Skip(ABO + i*0x1000).Take(chunkLength[BlockOrder[i]]).ToArray();
|
||||
ushort chk = SaveUtil.check32(chunk);
|
||||
BitConverter.GetBytes(chk).CopyTo(Data, ABO + i + 0xFF4);
|
||||
}
|
||||
}
|
||||
public override bool ChecksumsValid
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
byte[] chunk = Data.Skip(ABO + i * 0x1000).Take(chunkLength[BlockOrder[i]]).ToArray();
|
||||
ushort chk = SaveUtil.check32(chunk);
|
||||
if (chk != BitConverter.ToUInt16(Data, ABO + i*0xFF4))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public override string ChecksumInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
string r = "";
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
byte[] chunk = Data.Skip(ABO + i * 0x1000).Take(chunkLength[BlockOrder[i]]).ToArray();
|
||||
ushort chk = SaveUtil.check32(chunk);
|
||||
if (chk != BitConverter.ToUInt16(Data, ABO + i * 0xFF4))
|
||||
r += $"Block {BlockOrder[i]} @ {i*0x1000} (len {chunkLength[BlockOrder[i]]}) invalid." + Environment.NewLine;
|
||||
}
|
||||
return r.Length == 0 ? "Checksums valid." : r.TrimEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// Trainer Info
|
||||
public override GameVersion Version
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (SaveVersion)
|
||||
{
|
||||
case 0: return GameVersion.RS;
|
||||
case 1: return GameVersion.FRLG;
|
||||
case 2: return GameVersion.E;
|
||||
}
|
||||
return GameVersion.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private bool Japanese;
|
||||
private uint SecurityKey
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.E: return BitConverter.ToUInt32(Data, Trainer1 + 0xAC);
|
||||
case GameVersion.FRLG: return BitConverter.ToUInt32(Data, Trainer1 + 0xAF8);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override string OT
|
||||
{
|
||||
get
|
||||
{
|
||||
return PKX.getG3Str(Data.Skip(Trainer1).Take(0x10).ToArray(), Japanese)
|
||||
.Replace("\uE08F", "\u2640") // Nidoran ♂
|
||||
.Replace("\uE08E", "\u2642") // Nidoran ♀
|
||||
.Replace("\u2019", "\u0027"); // Farfetch'd
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value.Length > 7)
|
||||
value = value.Substring(0, 7); // Hard cap
|
||||
string TempNick = value // Replace Special Characters and add Terminator
|
||||
.Replace("\u2640", "\uE08F") // Nidoran ♂
|
||||
.Replace("\u2642", "\uE08E") // Nidoran ♀
|
||||
.Replace("\u0027", "\u2019"); // Farfetch'd
|
||||
PKX.setG3Str(TempNick, Japanese).CopyTo(Data, Trainer1);
|
||||
}
|
||||
}
|
||||
public override int Gender
|
||||
{
|
||||
get { return Data[Trainer1 + 8]; }
|
||||
set { Data[Trainer1 + 8] = (byte)value; }
|
||||
}
|
||||
public override ushort TID
|
||||
{
|
||||
get { return BitConverter.ToUInt16(Data, Trainer1 + 0xA + 0); }
|
||||
set { BitConverter.GetBytes(value).CopyTo(Data, Trainer1 + 0xA + 0); }
|
||||
}
|
||||
public override ushort SID
|
||||
{
|
||||
get { return BitConverter.ToUInt16(Data, Trainer1 + 0xC); }
|
||||
set { BitConverter.GetBytes(value).CopyTo(Data, Trainer1 + 0xC); }
|
||||
}
|
||||
public override int PlayedHours
|
||||
{
|
||||
get { return BitConverter.ToUInt16(Data, Trainer1 + 0xE); }
|
||||
set { BitConverter.GetBytes((ushort)value).CopyTo(Data, Trainer1 + 0xE); }
|
||||
}
|
||||
public override int PlayedMinutes
|
||||
{
|
||||
get { return Data[Trainer1 + 0x10]; }
|
||||
set { Data[Trainer1 + 0x10] = (byte)value; }
|
||||
}
|
||||
public override int PlayedSeconds
|
||||
{
|
||||
get { return Data[Trainer1 + 0x11]; }
|
||||
set { Data[Trainer1 + 0x11] = (byte)value; }
|
||||
}
|
||||
public int PlayedFrames
|
||||
{
|
||||
get { return Data[Trainer1 + 0x12]; }
|
||||
set { Data[Trainer1 + 0x12] = (byte)value; }
|
||||
}
|
||||
|
||||
public override uint Money
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.RS:
|
||||
case GameVersion.E: return BitConverter.ToUInt32(Data, Party + 0x0490) ^ SecurityKey;
|
||||
case GameVersion.FRLG: return BitConverter.ToUInt32(Data, Party + 0x0290) ^ SecurityKey;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.RS:
|
||||
case GameVersion.E: BitConverter.GetBytes(value ^ SecurityKey).CopyTo(Data, Party + 0x0490); break;
|
||||
case GameVersion.FRLG: BitConverter.GetBytes(value ^ SecurityKey).CopyTo(Data, Party + 0x0290); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public uint Coin
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.RS:
|
||||
case GameVersion.E: return BitConverter.ToUInt32(Data, Party + 0x0494) ^ SecurityKey;
|
||||
case GameVersion.FRLG: return BitConverter.ToUInt32(Data, Party + 0x0294) ^ SecurityKey;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.RS:
|
||||
case GameVersion.E: BitConverter.GetBytes(value ^ SecurityKey).CopyTo(Data, Party + 0x0494); break;
|
||||
case GameVersion.FRLG: BitConverter.GetBytes(value ^ SecurityKey).CopyTo(Data, Party + 0x0294); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
public int BP
|
||||
{
|
||||
get { return Data[Trainer1 + 0xEB8]; }
|
||||
set { Data[Trainer1 + 0xEB8] = (byte)value; }
|
||||
}
|
||||
|
||||
public override InventoryPouch[] Inventory
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
|
||||
}
|
||||
set { }
|
||||
}
|
||||
public override int Language { get { return 0; } set { } }
|
||||
|
||||
public override int getDaycareSlotOffset(int loc, int slot)
|
||||
{
|
||||
return Daycare + slot * SIZE_PARTY;
|
||||
}
|
||||
public override ulong? getDaycareRNGSeed(int loc)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override uint? getDaycareEXP(int loc, int slot)
|
||||
{
|
||||
int ofs = Daycare + (slot + 1) * SIZE_PARTY - 4;
|
||||
return BitConverter.ToUInt32(Data, ofs);
|
||||
}
|
||||
public override bool? getDaycareOccupied(int loc, int slot)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public override void setDaycareEXP(int loc, int slot, uint EXP)
|
||||
{
|
||||
int ofs = Daycare + (slot + 1) * SIZE_PARTY - 4;
|
||||
BitConverter.GetBytes(EXP).CopyTo(Data, ofs);
|
||||
}
|
||||
public override void setDaycareOccupied(int loc, int slot, bool occupied)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Storage
|
||||
public override int PartyCount
|
||||
{
|
||||
get
|
||||
{
|
||||
int ofs = 0x34;
|
||||
if (GameVersion.FRLG != Version)
|
||||
ofs += 0x200;
|
||||
return Data[Party + ofs];
|
||||
|
||||
}
|
||||
protected set
|
||||
{
|
||||
int ofs = 0x34;
|
||||
if (GameVersion.FRLG != Version)
|
||||
ofs += 0x200;
|
||||
Data[Party + ofs] = (byte)value;
|
||||
}
|
||||
}
|
||||
public override int getBoxOffset(int box)
|
||||
{
|
||||
return Box + 4 + SIZE_STORED * box * 30;
|
||||
}
|
||||
public override int getPartyOffset(int slot)
|
||||
{
|
||||
int ofs = 0x38;
|
||||
if (GameVersion.FRLG != Version)
|
||||
ofs += 0x200;
|
||||
return Party + ofs + SIZE_PARTY * slot;
|
||||
}
|
||||
public override int CurrentBox
|
||||
{
|
||||
get { return Data[Box]; }
|
||||
set { Data[Box] = (byte)value; }
|
||||
}
|
||||
public override int getBoxWallpaper(int box)
|
||||
{
|
||||
// Box Wallpaper is directly after the Box Names
|
||||
int offset = getBoxOffset(BoxCount);
|
||||
offset += BoxCount * 0x9;
|
||||
return Data[offset];
|
||||
}
|
||||
public override string getBoxName(int box)
|
||||
{
|
||||
int offset = getBoxOffset(BoxCount);
|
||||
return PKX.getG3Str(Data.Skip(offset + box * 9).Take(9).ToArray(), Japanese);
|
||||
}
|
||||
public override void setBoxName(int box, string value)
|
||||
{
|
||||
if (value.Length > 8)
|
||||
value = value.Substring(0, 8); // Hard cap
|
||||
int offset = getBoxOffset(BoxCount);
|
||||
PKX.setG3Str(value, Japanese).CopyTo(Data, offset + box * 9);
|
||||
}
|
||||
public override PKM getPKM(byte[] data)
|
||||
{
|
||||
return new PK3(data);
|
||||
}
|
||||
public override byte[] decryptPKM(byte[] data)
|
||||
{
|
||||
return PKX.decryptArray3(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -568,7 +568,6 @@ public override byte[] decryptPKM(byte[] data)
|
||||
}
|
||||
|
||||
// Daycare
|
||||
public override int DaycareSeedSize => 8;
|
||||
public override int getDaycareSlotOffset(int loc, int slot)
|
||||
{
|
||||
return Daycare + slot * SIZE_PARTY;
|
||||
|
||||
@@ -84,7 +84,7 @@ public byte[] Write(bool DSV)
|
||||
protected virtual int GiftFlagMax { get; } = 0x800;
|
||||
protected virtual int EventFlagMax { get; } = int.MinValue;
|
||||
protected virtual int EventConstMax { get; } = int.MinValue;
|
||||
public abstract int DaycareSeedSize { get; }
|
||||
public virtual int DaycareSeedSize { get; } = 0;
|
||||
public abstract int OTLength { get; }
|
||||
public abstract int NickLength { get; }
|
||||
|
||||
@@ -249,8 +249,8 @@ public ushort[] EventConsts
|
||||
protected int OFS_MailItems { get; set; } = int.MinValue;
|
||||
|
||||
// Mystery Gift
|
||||
protected abstract bool[] MysteryGiftReceivedFlags { get; set; }
|
||||
protected abstract MysteryGift[] MysteryGiftCards { get; set; }
|
||||
protected virtual bool[] MysteryGiftReceivedFlags { get { return null; } set { } }
|
||||
protected virtual MysteryGift[] MysteryGiftCards { get { return null; } set { } }
|
||||
public virtual MysteryGiftAlbum GiftAlbum
|
||||
{
|
||||
get
|
||||
@@ -285,8 +285,8 @@ public virtual MysteryGiftAlbum GiftAlbum
|
||||
public abstract int PlayedHours { get; set; }
|
||||
public abstract int PlayedMinutes { get; set; }
|
||||
public abstract int PlayedSeconds { get; set; }
|
||||
public abstract int SecondsToStart { get; set; }
|
||||
public abstract int SecondsToFame { get; set; }
|
||||
public virtual int SecondsToStart { get; set; }
|
||||
public virtual int SecondsToFame { get; set; }
|
||||
public abstract uint Money { get; set; }
|
||||
public abstract int BoxCount { get; }
|
||||
public abstract int PartyCount { get; protected set; }
|
||||
|
||||
@@ -14,6 +14,8 @@ public enum GameVersion
|
||||
X = 24, Y = 25, AS = 26, OR = 27,
|
||||
SN = 28, MN = 29,
|
||||
|
||||
RS = 200,
|
||||
FRLG = 201,
|
||||
DP = 100,
|
||||
HGSS = 101,
|
||||
}
|
||||
@@ -28,11 +30,15 @@ internal static class SaveUtil
|
||||
internal const int SIZE_G5BW = 0x24000;
|
||||
internal const int SIZE_G5B2W2 = 0x26000;
|
||||
internal const int SIZE_G4RAW = 0x80000;
|
||||
internal const int SIZE_G3RAW = 0x20000;
|
||||
internal const int SIZE_G3RAWHALF = 0x10000;
|
||||
|
||||
internal static readonly byte[] FOOTER_DSV = Encoding.ASCII.GetBytes("|-DESMUME SAVE-|");
|
||||
|
||||
internal static int getSAVGeneration(byte[] data)
|
||||
{
|
||||
if (getIsG3SAV(data) != -1)
|
||||
return 3;
|
||||
if (getIsG4SAV(data) != -1)
|
||||
return 4;
|
||||
if (getIsG5SAV(data) != -1)
|
||||
@@ -41,6 +47,24 @@ internal static int getSAVGeneration(byte[] data)
|
||||
return 6;
|
||||
return -1;
|
||||
}
|
||||
internal static int getIsG3SAV(byte[] data)
|
||||
{
|
||||
if (data.Length != SIZE_G3RAW && data.Length != SIZE_G3RAWHALF)
|
||||
return -1;
|
||||
|
||||
int[] BlockOrder = new int[14];
|
||||
for (int i = 0; i < 14; i++)
|
||||
BlockOrder[i] = BitConverter.ToInt16(data, i * 0x1000 + 0xFF4);
|
||||
|
||||
if (BlockOrder.Any(i => i > 0xD || i < 0))
|
||||
return -1;
|
||||
|
||||
// Detect RS/E/FRLG
|
||||
// Section 0 stores Game Code @ 0x00AC; 0 for RS, 1 for FRLG, else for Emerald
|
||||
|
||||
uint GameCode = BitConverter.ToUInt32(data, Array.IndexOf(BlockOrder, 0) * 0x1000);
|
||||
return GameCode < 2 ? (int)GameCode : 2;
|
||||
}
|
||||
internal static int getIsG4SAV(byte[] data)
|
||||
{
|
||||
if (data.Length != SIZE_G4RAW)
|
||||
@@ -103,6 +127,8 @@ internal static SaveFile getVariantSAV(byte[] data)
|
||||
{
|
||||
switch (getSAVGeneration(data))
|
||||
{
|
||||
case 3:
|
||||
return new SAV3(data);
|
||||
case 4:
|
||||
return new SAV4(data);
|
||||
case 5:
|
||||
@@ -276,6 +302,16 @@ internal static void writeG6CHK(byte[] savefile)
|
||||
BitConverter.GetBytes(ccitt16(array)).CopyTo(savefile, verificationOffset + 6 + i * 8);
|
||||
}
|
||||
}
|
||||
/// <summary>Calculates the 32bit checksum over an input byte array. Used in GBA save files.</summary>
|
||||
/// <param name="data">Input byte array</param>
|
||||
/// <returns>Checksum</returns>
|
||||
internal static ushort check32(byte[] data)
|
||||
{
|
||||
uint val = 0;
|
||||
for (int i = 0; i < data.Length; i += 4)
|
||||
val += BitConverter.ToUInt32(data, i);
|
||||
return (ushort)(val + val >> 16);
|
||||
}
|
||||
|
||||
internal static int getDexFormIndexXY(int species, int formct)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user