mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-11 07:04:16 +00:00
Add ranch r(/w?) support
not gonna edit the metadata properly handle an irregular sized display box
This commit is contained in:
parent
f0d9e3f2e5
commit
ae6010f169
8 changed files with 112 additions and 14 deletions
|
@ -411,7 +411,7 @@ namespace PKHeX.Core
|
|||
public virtual int SecondsToFame { get; set; }
|
||||
public virtual uint Money { get; set; }
|
||||
public abstract int BoxCount { get; }
|
||||
public int SlotCount => BoxCount * BoxSlotCount;
|
||||
public virtual int SlotCount => BoxCount * BoxSlotCount;
|
||||
public virtual int PartyCount { get; protected set; }
|
||||
public virtual int MultiplayerSpriteID { get => 0; set { } }
|
||||
|
||||
|
@ -665,7 +665,7 @@ namespace PKHeX.Core
|
|||
PartyCount--;
|
||||
}
|
||||
|
||||
protected bool IsSlotSwapProtected(int box, int slot) => false;
|
||||
protected virtual bool IsSlotSwapProtected(int box, int slot) => false;
|
||||
|
||||
private bool IsRegionOverwriteProtected(int min, int max)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,5 @@ namespace PKHeX.Core
|
|||
public override int GetBoxOffset(int box) => Box + (BoxDataSize * box);
|
||||
public override string GetBoxName(int box) => GetString(GetBoxNameOffset(box), BoxNameSize);
|
||||
private int GetBoxNameOffset(int box) => 0x25800 + (9 * box);
|
||||
|
||||
public static Bank3 GetBank3(byte[] data) => new Bank3(data);
|
||||
}
|
||||
}
|
|
@ -24,7 +24,5 @@ namespace PKHeX.Core
|
|||
public override int GetBoxOffset(int box) => Box + (BoxDataSize * box);
|
||||
public override string GetBoxName(int box) => GetString(GetBoxNameOffset(box), BoxNameSize / 2);
|
||||
private int GetBoxNameOffset(int box) => 0x3FC00 + (0x19 * box);
|
||||
|
||||
public static Bank4 GetBank4(byte[] data) => new Bank4(data);
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ namespace PKHeX.Core
|
|||
public override int MaxGameID => blank.MaxGameID;
|
||||
public override int OTLength => blank.OTLength;
|
||||
public override int NickLength => blank.NickLength;
|
||||
public bool BigEndian => blank is BK4 || blank is XK3 || blank is CK3;
|
||||
public bool IsBigEndian => blank is BK4 || blank is XK3 || blank is CK3;
|
||||
|
||||
private readonly Func<byte[], int, bool> GetIsPKMPresent;
|
||||
public override bool IsPKMPresent(int Offset) => GetIsPKMPresent(Data, Offset);
|
||||
|
@ -65,9 +65,9 @@ namespace PKHeX.Core
|
|||
public override int GetPartyOffset(int slot) => int.MinValue;
|
||||
|
||||
public override string GetString(byte[] data, int offset, int length)
|
||||
=> StringConverter.GetString(data, Generation, blank.Japanese, BigEndian, length, offset);
|
||||
=> StringConverter.GetString(data, Generation, blank.Japanese, IsBigEndian, length, offset);
|
||||
|
||||
public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0)
|
||||
=> StringConverter.SetString(value, Generation, blank.Japanese, BigEndian, maxLength, padTo: PadToSize, padWith: PadWith);
|
||||
=> StringConverter.SetString(value, Generation, blank.Japanese, IsBigEndian, maxLength, padTo: PadToSize, padWith: PadWith);
|
||||
}
|
||||
}
|
||||
|
|
96
PKHeX.Core/Saves/Storage/SAV4Ranch.cs
Normal file
96
PKHeX.Core/Saves/Storage/SAV4Ranch.cs
Normal file
|
@ -0,0 +1,96 @@
|
|||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public sealed class SAV4Ranch : BulkStorage
|
||||
{
|
||||
private const int SIZE_MII = 0x28;
|
||||
private const int SIZE_MIILINK = 0x2C;
|
||||
|
||||
public override int SIZE_STORED => 0x88 + 0x1C;
|
||||
protected override int SIZE_PARTY => SIZE_STORED;
|
||||
|
||||
public override int BoxCount { get; }
|
||||
public override int SlotCount { get; }
|
||||
|
||||
public override string PlayTimeString => SaveUtil.CRC16(Data, 0, Data.Length).ToString("X4");
|
||||
protected override string BAKText => $"{OT} {PlayTimeString}";
|
||||
public override string Extension => ".bin";
|
||||
public override string Filter { get; } = "Ranch G4 Storage|*.bin*";
|
||||
|
||||
public override PKM GetPKM(byte[] data) => new PK4(data);
|
||||
public override byte[] DecryptPKM(byte[] data) => PKX.DecryptArray45(data);
|
||||
public override StorageSlotFlag GetSlotFlags(int index) => index >= SlotCount ? StorageSlotFlag.Locked : StorageSlotFlag.None;
|
||||
protected override bool IsSlotSwapProtected(int box, int slot) => IsSlotOverwriteProtected(box, slot);
|
||||
|
||||
public SAV4Ranch(byte[] data) : base(data, typeof(PK4), 0)
|
||||
{
|
||||
Personal = PersonalTable.Pt;
|
||||
Version = GameVersion.DPPt;
|
||||
HeldItems = Legal.HeldItems_Pt;
|
||||
|
||||
OT = GetString(0x770, 0x12);
|
||||
|
||||
// Unpack the binary a little:
|
||||
// count, Mii data[count]
|
||||
// count, Mii Link data[count]
|
||||
// count, Pokemon (PK4 + metadata)[count]
|
||||
|
||||
/* ====Metadata====
|
||||
* uint8_t poke_type;// 01 trainer, 04 hayley, 05 traded
|
||||
* uint8_t tradeable;// 02 is tradeable, normal 00
|
||||
* uint16_t tid;
|
||||
* uint16_t sid;
|
||||
* uint32_t name1;
|
||||
* uint32_t name2;
|
||||
* uint32_t name3;
|
||||
* uint32_t name4;
|
||||
*/
|
||||
|
||||
const int miiCountOffset = 0x22AC;
|
||||
var miiCount = BigEndian.ToInt32(Data, miiCountOffset);
|
||||
var miiLinkCountOffset = miiCountOffset + 4 + (SIZE_MII * miiCount) + 4;
|
||||
var miiLinkCount = BigEndian.ToInt32(Data, miiLinkCountOffset);
|
||||
var pkCountOffset = miiLinkCountOffset + 4 + (SIZE_MIILINK * miiLinkCount) + 4;
|
||||
|
||||
SlotCount = BigEndian.ToInt32(Data, pkCountOffset);
|
||||
BoxCount = (int)Math.Ceiling((decimal)SlotCount / SlotsPerBox);
|
||||
|
||||
Box = pkCountOffset + 4;
|
||||
|
||||
FinalCountOffset = pkCountOffset + 4 + (SIZE_STORED * SlotCount);
|
||||
FinalCount = BigEndian.ToInt32(Data, FinalCountOffset);
|
||||
}
|
||||
|
||||
private readonly int FinalCount;
|
||||
private readonly int FinalCountOffset;
|
||||
|
||||
protected override void SetChecksums()
|
||||
{
|
||||
BigEndian.GetBytes(FinalCount).CopyTo(Data, FinalCountOffset); // ensure the final data is written if the user screws stuff up
|
||||
var goodlen = (FinalCountOffset + 4);
|
||||
Array.Clear(Data, goodlen, Data.Length - goodlen);
|
||||
|
||||
// 20 byte SHA checksum at the top of the file, which covers all data that follows.
|
||||
using (var hash = SHA1.Create())
|
||||
{
|
||||
var result = hash.ComputeHash(Data, 20, Data.Length - 20);
|
||||
SetData(result, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetString(byte[] data, int offset, int length) => Util.TrimFromZero(Encoding.BigEndianUnicode.GetString(data, offset, length));
|
||||
|
||||
public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0)
|
||||
{
|
||||
if (value.Length > maxLength)
|
||||
value = value.Substring(0, maxLength); // Hard cap
|
||||
string temp = value
|
||||
.PadRight(value.Length + 1, (char)0) // Null Terminator
|
||||
.PadRight(PadToSize, (char)PadWith); // Padding
|
||||
return Encoding.BigEndianUnicode.GetBytes(temp);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -103,7 +103,7 @@ namespace PKHeX.Core
|
|||
public static int ImportPKMs(this SaveFile SAV, IEnumerable<PKM> compat, bool overwrite = false, int boxStart = 0, bool? noSetb = null)
|
||||
{
|
||||
int startCount = boxStart * SAV.BoxSlotCount;
|
||||
int maxCount = SAV.BoxCount * SAV.BoxSlotCount;
|
||||
int maxCount = SAV.SlotCount;
|
||||
int index = startCount;
|
||||
|
||||
foreach (var pk in compat)
|
||||
|
|
|
@ -48,6 +48,7 @@ namespace PKHeX.Core
|
|||
// Bank Binaries
|
||||
public const int SIZE_G7BANK = 0xACA48;
|
||||
public const int SIZE_G4BANK = 0x405C4;
|
||||
public const int SIZE_G4RANCH = 0x54000;
|
||||
|
||||
private static readonly HashSet<int> SIZES_2 = new HashSet<int>
|
||||
{
|
||||
|
@ -64,7 +65,7 @@ namespace PKHeX.Core
|
|||
// SIZES_2 covers gen2 sizes since there's so many
|
||||
SIZE_G1RAW, SIZE_G1BAT,
|
||||
|
||||
SIZE_G7BANK, SIZE_G4BANK,
|
||||
SIZE_G7BANK, SIZE_G4BANK, SIZE_G4RANCH,
|
||||
};
|
||||
|
||||
private static readonly int[] mainSizes = { SIZE_G6XY, SIZE_G6ORAS, SIZE_G7SM, SIZE_G7USUM };
|
||||
|
@ -111,6 +112,8 @@ namespace PKHeX.Core
|
|||
return GameVersion.HGSS;
|
||||
if (GetIsBank3(data)) // pokestock
|
||||
return GameVersion.RS;
|
||||
if (GetIsRanch4(data)) // ranch
|
||||
return GameVersion.DP;
|
||||
|
||||
return GameVersion.Invalid;
|
||||
}
|
||||
|
@ -444,6 +447,7 @@ namespace PKHeX.Core
|
|||
private static bool GetIsBank7(byte[] data) => data.Length == SIZE_G7BANK && data[0] != 0;
|
||||
private static bool GetIsBank4(byte[] data) => data.Length == SIZE_G4BANK && BitConverter.ToUInt32(data, 0x3FC00) != 0; // box name present
|
||||
private static bool GetIsBank3(byte[] data) => data.Length == SIZE_G4BANK && BitConverter.ToUInt32(data, 0x3FC00) == 0; // size collision with ^
|
||||
private static bool GetIsRanch4(byte[] data) => data.Length == SIZE_G4RANCH && BigEndian.ToUInt32(data, 0x22AC) != 0;
|
||||
|
||||
/// <summary>Creates an instance of a SaveFile using the given save data.</summary>
|
||||
/// <param name="path">File location from which to create a SaveFile.</param>
|
||||
|
@ -493,9 +497,10 @@ namespace PKHeX.Core
|
|||
case GameVersion.GG: return new SAV7b(data);
|
||||
|
||||
// Bulk Storage
|
||||
case GameVersion.RS: return new Bank3(data);
|
||||
case GameVersion.DP: return new SAV4Ranch(data);
|
||||
case GameVersion.HGSS: return new Bank4(data);
|
||||
case GameVersion.USUM: return Bank7.GetBank7(data);
|
||||
case GameVersion.HGSS: return Bank4.GetBank4(data);
|
||||
case GameVersion.RS: return Bank3.GetBank3(data);
|
||||
|
||||
// No pattern matched
|
||||
default: return null;
|
||||
|
|
|
@ -167,10 +167,11 @@ namespace PKHeX.WinForms.Controls
|
|||
|
||||
int slot = M?.ColorizedBox == box ? M.ColorizedSlot : -1;
|
||||
|
||||
int index = box * SAV.BoxSlotCount;
|
||||
for (int i = 0; i < BoxSlotCount; i++)
|
||||
{
|
||||
var pb = SlotPictureBoxes[i];
|
||||
if (i < SAV.BoxSlotCount)
|
||||
if (i < SAV.BoxSlotCount && index + i < SAV.SlotCount)
|
||||
GetSlotFiller(boxoffset + (SAV.SIZE_STORED * i), pb, box, i);
|
||||
else
|
||||
pb.Visible = false;
|
||||
|
|
Loading…
Reference in a new issue