using System; using System.Linq; namespace PKHeX.Core { public abstract class MysteryGift : IEncounterable, IMoveset { /// /// Determines whether or not the given length of bytes is valid for a mystery gift. /// /// Length, in bytes, of the data of which to determine validity. /// A boolean indicating whether or not the given length is valid for a mystery gift. public static bool IsMysteryGift(long len) { return new[] { WC6.SizeFull, WC6.Size, PGF.Size, PGT.Size, PCD.Size }.Contains((int)len); } /// /// Converts the given data to a . /// /// Raw data of the mystery gift. /// Extension of the file from which the was retrieved. /// An instance of representing the given data, or null if or is invalid. /// This overload differs from by checking the / combo for validity. If either is invalid, a null reference is returned. public static MysteryGift GetMysteryGift(byte[] data, string ext) { // Generation 7 if (data.Length == WC7.SizeFull && ext == ".wc7full") return new WC7(data); if (data.Length == WC7.Size && ext == ".wc7") return new WC7(data); // Generation 6 if (data.Length == WC6.SizeFull && ext == ".wc6full") return new WC6(data); if (data.Length == WC6.Size && ext == ".wc6") return new WC6(data); // Generation 5 if (data.Length == PGF.Size && ext == ".pgf") return new PGF(data); // Generation 4 if (data.Length == PGT.Size && ext == ".pgt") return new PGT(data); if (data.Length == PCD.Size && ext == ".pcd") return new PCD(data); return null; } /// /// Converts the given data to a . /// /// Raw data of the mystery gift. /// An instance of representing the given data, or null if is invalid. public static MysteryGift GetMysteryGift(byte[] data) { switch (data.Length) { case WC6.SizeFull: // Check WC7 size collision if (data[0x205] == 0) // 3 * 0x46 for gen6, now only 2. return new WC7(data); return new WC6(data); case WC6.Size: // Check year for WC7 size collision if (BitConverter.ToUInt32(data, 0x4C) / 10000 < 2000) return new WC7(data); return new WC6(data); case PGF.Size: return new PGF(data); case PGT.Size: return new PGT(data); case PCD.Size: return new PCD(data); default: return null; } } public string Extension => GetType().Name.ToLower(); public string FileName => $"{CardHeader}.{Extension}"; public byte[] Data { get; set; } public abstract PKM ConvertToPKM(SaveFile SAV); public abstract int Format { get; } public MysteryGift Clone() { byte[] data = (byte[])Data.Clone(); return GetMysteryGift(data); } public string Type => GetType().Name; public string Name => $"Event Gift ({Type})"; // Properties public virtual int Species { get => -1; set { } } public abstract bool GiftUsed { get; set; } public abstract string CardTitle { get; set; } public abstract int CardID { get; set; } public abstract bool IsItem { get; set; } public abstract int ItemID { get; set; } public abstract bool IsPokémon { get; set; } public virtual int Quantity { get => 1; set { } } public virtual bool Empty => Data.All(z => z == 0); public virtual bool IsBP { get => false; set { } } public virtual int BP { get => 0; set { } } public virtual bool IsBean { get => false; set { } } public virtual int Bean { get => 0; set { } } public virtual int BeanCount { get => 0; set { } } public virtual string CardHeader => (CardID > 0 ? $"Card #: {CardID:0000}" : "N/A") + $" - {CardTitle.Replace('\u3000',' ').Trim()}"; public override int GetHashCode() { int hash = 17; foreach (var b in Data) hash = hash*31 + b; return hash; } // Search Properties public virtual int[] Moves { get => new int[4]; set { } } public virtual int[] RelearnMoves { get => new int[4]; set { } } public virtual bool IsShiny => false; public virtual bool IsEgg { get => false; set { } } public virtual int HeldItem { get => -1; set { } } public virtual object Content => this; public abstract int Level { get; set; } public int LevelMin => Level; public int LevelMax => Level; public abstract int Ball { get; set; } public bool Gen7 => Format == 7; public bool Gen6 => Format == 6; public bool Gen5 => Format == 5; public bool Gen4 => Format == 4; public bool Gen3 => Format == 3; public virtual bool EggEncounter => IsEgg; } }