mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
Minor xmldoc / usage updates
This commit is contained in:
parent
c11cf3d6d4
commit
41096fb56e
24 changed files with 247 additions and 122 deletions
|
@ -137,7 +137,7 @@ namespace PKHeX.Core
|
|||
otname.CopyTo(pk2.otname, 0);
|
||||
nick.CopyTo(pk2.nick, 0);
|
||||
|
||||
pk2.HeldItem = ItemConverter.GetItemFuture1(pk2.HeldItem);
|
||||
pk2.HeldItem = Gen2Item;
|
||||
pk2.CurrentFriendship = pk2.PersonalInfo.BaseFriendship;
|
||||
pk2.Stat_Level = CurrentLevel;
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@ namespace PKHeX.Core
|
|||
{
|
||||
public override PersonalInfo PersonalInfo => PersonalTable.C[Species];
|
||||
|
||||
public override bool Valid => Species <= 252;
|
||||
internal const byte EggSpeciesValue = 0xFD;
|
||||
public override bool Valid => Species is <= Legal.MaxSpeciesID_2 or EggSpeciesValue; // egg
|
||||
|
||||
public override int SIZE_PARTY => PokeCrypto.SIZE_2PARTY;
|
||||
public override int SIZE_STORED => PokeCrypto.SIZE_2STORED;
|
||||
|
|
|
@ -2,7 +2,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
public sealed class PokeList2 : PokeListGB<PK2>
|
||||
{
|
||||
protected override byte GetSpeciesBoxIdentifier(PK2 pk) => pk.IsEgg ? 0xFD : (byte)pk.Species;
|
||||
protected override byte GetSpeciesBoxIdentifier(PK2 pk) => pk.IsEgg ? PK2.EggSpeciesValue : (byte)pk.Species;
|
||||
protected override PK2 GetEntry(byte[] dat, byte[] otname, byte[] nick, bool egg) => new(dat, Japanese) { OT_Trash = otname, Nickname_Trash = nick, IsEgg = egg };
|
||||
protected override int GetEntrySize() => GetEntrySize(IsFormatParty);
|
||||
|
||||
|
@ -14,4 +14,4 @@ namespace PKHeX.Core
|
|||
private static int GetEntrySize(bool party) => party ? PokeCrypto.SIZE_2PARTY : PokeCrypto.SIZE_2STORED;
|
||||
public static int GetDataLength(PokeListType c, bool jp) => GetDataSize(c, jp, GetEntrySize(IsCapacityPartyFormat(c)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace PKHeX.Core
|
|||
/// </summary>
|
||||
internal static class ItemConverter
|
||||
{
|
||||
/// <summary>Unused item ID, placeholder for item/sprite finding</summary>
|
||||
/// <summary>Unused item ID, placeholder for item/sprite finding in Generations 2-4.</summary>
|
||||
private const ushort NaN = 128;
|
||||
|
||||
/// <summary>
|
||||
|
@ -150,7 +150,7 @@ namespace PKHeX.Core
|
|||
};
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Gen1 Item to Gen2 Item.
|
||||
/// Converts a Gen1 <see cref="PK1.Catch_Rate"/> value to Gen2 Item.
|
||||
/// </summary>
|
||||
/// <param name="value">Gen1 Item</param>
|
||||
/// <returns>Gen2 Item</returns>
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace PKHeX.Core
|
|||
#endregion
|
||||
|
||||
#region Poketch
|
||||
public int PoketchStart { get; protected set; }
|
||||
protected int PoketchStart { private get; set; }
|
||||
private byte PoketchPacked { get => General[PoketchStart]; set => General[PoketchStart] = value; }
|
||||
|
||||
public bool PoketchEnabled { get => (PoketchPacked & 1) != 0; set => PoketchPacked = (byte)(value ? (PoketchPacked | 1) : (PoketchPacked & ~1)); }
|
||||
|
|
|
@ -4,21 +4,38 @@ namespace PKHeX.Core
|
|||
{
|
||||
public sealed class InventoryItem
|
||||
{
|
||||
/// <summary> Item ID </summary>
|
||||
public int Index;
|
||||
/// <summary> Quantity </summary>
|
||||
public int Count;
|
||||
|
||||
/// <summary> Indicates if the item is "NEW"ly obtained and not yet viewed. </summary>
|
||||
public bool New;
|
||||
|
||||
/// <summary> Indicates if the item should be shown in the Free Space pouch instead (Generation 5). </summary>
|
||||
public bool FreeSpace;
|
||||
public int Index, Count;
|
||||
|
||||
/// <summary> Creates a copy of the object. </summary>
|
||||
public InventoryItem Clone() => (InventoryItem) MemberwiseClone();
|
||||
|
||||
// Check Pouch Compatibility
|
||||
public bool Valid(IList<ushort> LegalItems, int MaxItemID, bool HaX = false)
|
||||
/// <summary>
|
||||
/// Checks if the item is compatible with a pouch.
|
||||
/// </summary>
|
||||
/// <param name="legal">Legal Item IDs for the pouch</param>
|
||||
/// <param name="maxItemID">Max item ID that exists in the game</param>
|
||||
/// <param name="HaX">Bend the rules for cheaters?</param>
|
||||
public bool IsValid(IList<ushort> legal, int maxItemID, bool HaX = false)
|
||||
{
|
||||
if (Index == 0)
|
||||
return true;
|
||||
if ((uint) Index > MaxItemID)
|
||||
if ((uint) Index > maxItemID)
|
||||
return false;
|
||||
return HaX || LegalItems.Contains((ushort)Index);
|
||||
return HaX || legal.Contains((ushort)Index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all data in the object back to zero.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
Index = Count = 0;
|
||||
|
|
|
@ -4,17 +4,31 @@ using System.Linq;
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the data in a pouch pocket containing items of a similar type group.
|
||||
/// </summary>
|
||||
public abstract class InventoryPouch
|
||||
{
|
||||
/// <inheritdoc cref="InventoryType"/>
|
||||
public readonly InventoryType Type;
|
||||
|
||||
/// <summary> Valid item IDs that may be stored in the pouch. </summary>
|
||||
public readonly ushort[] LegalItems;
|
||||
|
||||
/// <summary> Max quantity for a given item that can be stored in the pouch. </summary>
|
||||
public readonly int MaxCount;
|
||||
|
||||
/// <summary> Count of item slots occupied in the pouch. </summary>
|
||||
public int Count => Items.Count(it => it.Count > 0);
|
||||
|
||||
/// <summary> Checks if the player may run out of bag space when there are too many unique items to fit into the pouch. </summary>
|
||||
public bool IsCramped => LegalItems.Length > Items.Length;
|
||||
|
||||
public InventoryItem[] Items;
|
||||
|
||||
/// <summary> Offset the items were read from. </summary>
|
||||
protected readonly int Offset;
|
||||
/// <summary> Size of the backing byte array that represents the pouch. </summary>
|
||||
protected readonly int PouchDataSize;
|
||||
|
||||
protected InventoryPouch(InventoryType type, ushort[] legal, int maxCount, int offset, int size = -1)
|
||||
|
@ -27,10 +41,15 @@ namespace PKHeX.Core
|
|||
PouchDataSize = size > -1 ? size : legal.Length;
|
||||
}
|
||||
|
||||
public abstract void GetPouch(byte[] Data);
|
||||
public abstract void SetPouch(byte[] Data);
|
||||
/// <summary> Reads the pouch from the backing <see cref="data"/>. </summary>
|
||||
public abstract void GetPouch(byte[] data);
|
||||
/// <summary> Writes the pouch to the backing <see cref="data"/>. </summary>
|
||||
public abstract void SetPouch(byte[] data);
|
||||
|
||||
/// <summary> Orders the <see cref="Items"/> based on <see cref="InventoryItem.Count"/> </summary>
|
||||
public void SortByCount(bool reverse = false) => Array.Sort(Items, (x, y) => Compare(x.Count, y.Count, reverse));
|
||||
|
||||
/// <summary> Orders the <see cref="Items"/> based on <see cref="InventoryItem.Index"/> </summary>
|
||||
public void SortByIndex(bool reverse = false) => Array.Sort(Items, (x, y) => Compare(x.Index, y.Index, reverse));
|
||||
public void SortByName(string[] names, bool reverse = false) => Array.Sort(Items, (x, y) => Compare(x.Index, y.Index, names, reverse));
|
||||
public void SortByEmpty() => Array.Sort(Items, (x, y) => (x.Count == 0).CompareTo(y.Count == 0));
|
||||
|
@ -57,18 +76,26 @@ namespace PKHeX.Core
|
|||
: i1.CompareTo(i2);
|
||||
}
|
||||
|
||||
public void Sanitize(int MaxItemID, bool HaX = false)
|
||||
/// <summary>
|
||||
/// Clears invalid items and clamps any item quantity that is out of range.
|
||||
/// </summary>
|
||||
/// <param name="maxItemID">Max item ID that exists in the game</param>
|
||||
/// <param name="HaX">Allow maximum-but-illegal quantities.</param>
|
||||
public void Sanitize(int maxItemID, bool HaX = false)
|
||||
{
|
||||
int ctr = 0;
|
||||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
if (Items[i].Valid(LegalItems, MaxItemID, HaX))
|
||||
if (Items[i].IsValid(LegalItems, maxItemID, HaX))
|
||||
Items[ctr++] = Items[i];
|
||||
}
|
||||
while (ctr < Items.Length)
|
||||
Items[ctr++] = new InventoryItem();
|
||||
Items[ctr++].Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all item slots with a quantity of zero and shifts any subsequent item slot up.
|
||||
/// </summary>
|
||||
public void ClearCount0()
|
||||
{
|
||||
int ctr = 0;
|
||||
|
@ -78,39 +105,57 @@ namespace PKHeX.Core
|
|||
Items[ctr++] = Items[i];
|
||||
}
|
||||
while (ctr < Items.Length)
|
||||
Items[ctr++] = new InventoryItem();
|
||||
Items[ctr++].Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all items in the pouch.
|
||||
/// </summary>
|
||||
public void RemoveAll()
|
||||
{
|
||||
foreach (var item in Items)
|
||||
item.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all items in the pouch that match the criteria to delete.
|
||||
/// </summary>
|
||||
public void RemoveAll(Func<InventoryItem, bool> deleteCriteria)
|
||||
{
|
||||
foreach (var item in Items.Where(deleteCriteria))
|
||||
item.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all items in the pouch that match the criteria to delete, considering index within the pouch.
|
||||
/// </summary>
|
||||
public void RemoveAll(Func<InventoryItem, int, bool> deleteCriteria)
|
||||
{
|
||||
foreach (var item in Items.Where(deleteCriteria))
|
||||
item.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes all the item quantities of present items to the specified <see cref="value"/>.
|
||||
/// </summary>
|
||||
public void ModifyAllCount(int value)
|
||||
{
|
||||
foreach (var item in Items.Where(z => z.Count != 0))
|
||||
item.Count = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes all the item quantities of items that match the criteria to the specified <see cref="value"/>.
|
||||
/// </summary>
|
||||
public void ModifyAllCount(int value, Func<InventoryItem, bool> modifyCriteria)
|
||||
{
|
||||
foreach (var item in Items.Where(z => z.Count != 0).Where(modifyCriteria))
|
||||
item.Count = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes all the item quantities of items that match the criteria to the specified <see cref="value"/>, considering index within the pouch.
|
||||
/// </summary>
|
||||
public void ModifyAllCount(int value, Func<InventoryItem, int, bool> modifyCriteria)
|
||||
{
|
||||
foreach (var item in Items.Where(z => z.Count != 0).Where(modifyCriteria))
|
||||
|
@ -154,16 +199,15 @@ namespace PKHeX.Core
|
|||
var itemEnd = Math.Min(Items.Length, newItems.Count);
|
||||
for (int i = 0; i < itemEnd; i++)
|
||||
{
|
||||
var item = Items[i] = new InventoryItem
|
||||
{
|
||||
Index = newItems[i],
|
||||
Count = count,
|
||||
New = true,
|
||||
};
|
||||
var item = Items[i] = new InventoryItem {Index = newItems[i]};
|
||||
|
||||
var match = Array.Find(current, z => z.Index == newItems[i]);
|
||||
if (match == null)
|
||||
{
|
||||
item.Count = count;
|
||||
item.New = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// load old values
|
||||
item.Count = Math.Max(item.Count, match.Count);
|
||||
|
@ -214,17 +258,17 @@ namespace PKHeX.Core
|
|||
|
||||
public static class InventoryPouchExtensions
|
||||
{
|
||||
public static IReadOnlyList<InventoryPouch> LoadAll(this IReadOnlyList<InventoryPouch> value, byte[] Data)
|
||||
public static IReadOnlyList<InventoryPouch> LoadAll(this IReadOnlyList<InventoryPouch> value, byte[] data)
|
||||
{
|
||||
foreach (var p in value)
|
||||
p.GetPouch(Data);
|
||||
p.GetPouch(data);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void SaveAll(this IReadOnlyList<InventoryPouch> value, byte[] Data)
|
||||
public static void SaveAll(this IReadOnlyList<InventoryPouch> value, byte[] data)
|
||||
{
|
||||
foreach (var p in value)
|
||||
p.SetPouch(Data);
|
||||
p.SetPouch(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,29 +11,29 @@ namespace PKHeX.Core
|
|||
{
|
||||
}
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i<items.Length; i++)
|
||||
{
|
||||
items[i] = new InventoryItem
|
||||
{
|
||||
Index = BitConverter.ToUInt16(Data, Offset + (i* 4)),
|
||||
Count = BitConverter.ToUInt16(Data, Offset + (i* 4) + 2) ^ (ushort) SecurityKey
|
||||
Index = BitConverter.ToUInt16(data, Offset + (i* 4)),
|
||||
Count = BitConverter.ToUInt16(data, Offset + (i* 4) + 2) ^ (ushort) SecurityKey
|
||||
};
|
||||
}
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
||||
for (int i = 0; i<Items.Length; i++)
|
||||
{
|
||||
BitConverter.GetBytes((ushort) Items[i].Index).CopyTo(Data, Offset + (i* 4));
|
||||
BitConverter.GetBytes((ushort)((ushort) Items[i].Count ^ (ushort) SecurityKey)).CopyTo(Data, Offset + (i* 4) + 2);
|
||||
BitConverter.GetBytes((ushort) Items[i].Index).CopyTo(data, Offset + (i* 4));
|
||||
BitConverter.GetBytes((ushort)((ushort) Items[i].Count ^ (ushort) SecurityKey)).CopyTo(data, Offset + (i* 4) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,29 +9,29 @@ namespace PKHeX.Core
|
|||
{
|
||||
}
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
items[i] = new InventoryItem
|
||||
{
|
||||
Index = BigEndian.ToUInt16(Data, Offset + (i * 4)),
|
||||
Count = BigEndian.ToUInt16(Data, Offset + (i * 4) + 2)
|
||||
Index = BigEndian.ToUInt16(data, Offset + (i * 4)),
|
||||
Count = BigEndian.ToUInt16(data, Offset + (i * 4) + 2)
|
||||
};
|
||||
}
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
||||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
BigEndian.GetBytes((ushort)Items[i].Index).CopyTo(Data, Offset + (i * 4));
|
||||
BigEndian.GetBytes((ushort)Items[i].Count).CopyTo(Data, Offset + (i * 4) + 2);
|
||||
BigEndian.GetBytes((ushort)Items[i].Index).CopyTo(data, Offset + (i * 4));
|
||||
BigEndian.GetBytes((ushort)Items[i].Count).CopyTo(data, Offset + (i * 4) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,29 +16,29 @@ namespace PKHeX.Core
|
|||
// u16 id
|
||||
// u16 count
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
items[i] = new InventoryItem
|
||||
{
|
||||
Index = BitConverter.ToUInt16(Data, Offset + (i * 4)),
|
||||
Count = BitConverter.ToUInt16(Data, Offset + (i * 4) + 2)
|
||||
Index = BitConverter.ToUInt16(data, Offset + (i * 4)),
|
||||
Count = BitConverter.ToUInt16(data, Offset + (i * 4) + 2)
|
||||
};
|
||||
}
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
||||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
BitConverter.GetBytes((ushort)Items[i].Index).CopyTo(Data, Offset + (i * 4));
|
||||
BitConverter.GetBytes((ushort)Items[i].Count).CopyTo(Data, Offset + (i * 4) + 2);
|
||||
BitConverter.GetBytes((ushort)Items[i].Index).CopyTo(data, Offset + (i * 4));
|
||||
BitConverter.GetBytes((ushort)Items[i].Count).CopyTo(data, Offset + (i * 4) + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace PKHeX.Core
|
|||
public bool SetNew { get; set; } = false;
|
||||
private InventoryItem[] OriginalItems;
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
|
@ -24,7 +24,7 @@ namespace PKHeX.Core
|
|||
// 10bit freespace index
|
||||
// 1 bit new flag
|
||||
// 1 bit reserved
|
||||
uint val = BitConverter.ToUInt32(Data, Offset + (i * 4));
|
||||
uint val = BitConverter.ToUInt32(data, Offset + (i * 4));
|
||||
items[i] = new InventoryItem
|
||||
{
|
||||
Index = (int)(val & 0x3FF),
|
||||
|
@ -37,7 +37,7 @@ namespace PKHeX.Core
|
|||
OriginalItems = Items.Select(i => i.Clone()).ToArray();
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
@ -54,7 +54,7 @@ namespace PKHeX.Core
|
|||
val |= 0x40000000;
|
||||
if (Items[i].FreeSpace)
|
||||
val |= 0x100000;
|
||||
BitConverter.GetBytes(val).CopyTo(Data, Offset + (i * 4));
|
||||
BitConverter.GetBytes(val).CopyTo(data, Offset + (i * 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,19 +16,19 @@ namespace PKHeX.Core
|
|||
public bool SetNew { get; set; }
|
||||
private InventoryItem[] OriginalItems = Array.Empty<InventoryItem>();
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
uint val = BitConverter.ToUInt32(Data, Offset + (i * 4));
|
||||
uint val = BitConverter.ToUInt32(data, Offset + (i * 4));
|
||||
items[i] = GetItem(val);
|
||||
}
|
||||
Items = items;
|
||||
OriginalItems = Items.Select(i => i.Clone()).ToArray();
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
@ -36,7 +36,7 @@ namespace PKHeX.Core
|
|||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
uint val = SetItem(Items[i]);
|
||||
BitConverter.GetBytes(val).CopyTo(Data, Offset + (i * 4));
|
||||
BitConverter.GetBytes(val).CopyTo(data, Offset + (i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,19 @@ namespace PKHeX.Core
|
|||
public bool SetNew { get; set; }
|
||||
private InventoryItem[] OriginalItems = Array.Empty<InventoryItem>();
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
uint val = BitConverter.ToUInt32(Data, Offset + (i * 4));
|
||||
uint val = BitConverter.ToUInt32(data, Offset + (i * 4));
|
||||
items[i] = GetItem(val);
|
||||
}
|
||||
Items = items;
|
||||
OriginalItems = Items.Select(i => i.Clone()).ToArray();
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
@ -36,7 +36,7 @@ namespace PKHeX.Core
|
|||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
uint val = SetItem(Items[i]);
|
||||
BitConverter.GetBytes(val).CopyTo(Data, Offset + (i * 4));
|
||||
BitConverter.GetBytes(val).CopyTo(data, Offset + (i * 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace PKHeX.Core
|
|||
{
|
||||
}
|
||||
|
||||
public override void GetPouch(byte[] Data)
|
||||
public override void GetPouch(byte[] data)
|
||||
{
|
||||
var items = new InventoryItem[PouchDataSize];
|
||||
if (Type == InventoryType.TMHMs)
|
||||
|
@ -17,12 +17,12 @@ namespace PKHeX.Core
|
|||
int slot = 0;
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
if (Data[Offset + i] != 0)
|
||||
if (data[Offset + i] != 0)
|
||||
{
|
||||
items[slot++] = new InventoryItem
|
||||
{
|
||||
Index = LegalItems[i],
|
||||
Count = Data[Offset + i]
|
||||
Count = data[Offset + i]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
else
|
||||
{
|
||||
int numStored = Data[Offset];
|
||||
int numStored = data[Offset];
|
||||
if (numStored > PouchDataSize) // uninitialized yellow (0xFF), sanity check for out-of-bounds values
|
||||
numStored = 0;
|
||||
for (int i = 0; i < numStored; i++)
|
||||
|
@ -45,9 +45,9 @@ namespace PKHeX.Core
|
|||
items[i] = Type switch
|
||||
{
|
||||
InventoryType.KeyItems =>
|
||||
new InventoryItem {Index = Data[Offset + i + 1], Count = 1},
|
||||
new InventoryItem {Index = data[Offset + i + 1], Count = 1},
|
||||
_ =>
|
||||
new InventoryItem {Index = Data[Offset + (i * 2) + 1], Count = Data[Offset + (i * 2) + 2]}
|
||||
new InventoryItem {Index = data[Offset + (i * 2) + 1], Count = data[Offset + (i * 2) + 2]}
|
||||
};
|
||||
}
|
||||
for (int i = numStored; i < items.Length; i++)
|
||||
|
@ -62,7 +62,7 @@ namespace PKHeX.Core
|
|||
Items = items;
|
||||
}
|
||||
|
||||
public override void SetPouch(byte[] Data)
|
||||
public override void SetPouch(byte[] data)
|
||||
{
|
||||
if (Items.Length != PouchDataSize)
|
||||
throw new ArgumentException("Item array length does not match original pouch size.");
|
||||
|
@ -77,25 +77,25 @@ namespace PKHeX.Core
|
|||
int index = Array.FindIndex(LegalItems, it => t.Index == it);
|
||||
if (index < 0) // enforce correct pouch
|
||||
continue;
|
||||
Data[Offset + index] = (byte)t.Count;
|
||||
data[Offset + index] = (byte)t.Count;
|
||||
}
|
||||
break;
|
||||
case InventoryType.KeyItems:
|
||||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
Data[Offset + i + 1] = (byte)Items[i].Index;
|
||||
data[Offset + i + 1] = (byte)Items[i].Index;
|
||||
}
|
||||
Data[Offset] = (byte)Count;
|
||||
Data[Offset + 1 + Count] = 0xFF;
|
||||
data[Offset] = (byte)Count;
|
||||
data[Offset + 1 + Count] = 0xFF;
|
||||
break;
|
||||
default:
|
||||
for (int i = 0; i < Items.Length; i++)
|
||||
{
|
||||
Data[Offset + (i * 2) + 1] = (byte)Items[i].Index;
|
||||
Data[Offset + (i * 2) + 2] = (byte)Items[i].Count;
|
||||
data[Offset + (i * 2) + 1] = (byte)Items[i].Index;
|
||||
data[Offset + (i * 2) + 2] = (byte)Items[i].Count;
|
||||
}
|
||||
Data[Offset] = (byte)Count;
|
||||
Data[Offset + 1 + (2 * Count)] = 0xFF;
|
||||
data[Offset] = (byte)Count;
|
||||
data[Offset + 1 + (2 * Count)] = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ namespace PKHeX.Core
|
|||
/// <summary>
|
||||
/// Type of items the <see cref="InventoryPouch"/> contains.
|
||||
/// </summary>
|
||||
/// <remarks>Used by the Inventory Editor as the index for sprite lookup</remarks>
|
||||
/// <remarks>Used by the Inventory Editor as the index for sprite lookup.</remarks>
|
||||
public enum InventoryType
|
||||
{
|
||||
Items,
|
||||
|
|
|
@ -3,6 +3,9 @@ using System.Linq;
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for Pokédex logic operations.
|
||||
/// </summary>
|
||||
public abstract class ZukanBase
|
||||
{
|
||||
protected readonly SaveFile SAV;
|
||||
|
@ -14,18 +17,25 @@ namespace PKHeX.Core
|
|||
PokeDex = dex;
|
||||
}
|
||||
|
||||
#region Overall Info
|
||||
/// <summary> Count of unique Species Seen </summary>
|
||||
public int SeenCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetSeen);
|
||||
/// <summary> Count of unique Species Caught (Owned) </summary>
|
||||
public int CaughtCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetCaught);
|
||||
|
||||
public decimal PercentSeen => (decimal)SeenCount / SAV.MaxSpeciesID;
|
||||
public decimal PercentCaught => (decimal)CaughtCount / SAV.MaxSpeciesID;
|
||||
#endregion
|
||||
|
||||
/// <summary> Gets if the Species has been Seen by the player. </summary>
|
||||
public abstract bool GetSeen(int species);
|
||||
/// <summary> Gets if the Species has been Caught (Owned) by the player. </summary>
|
||||
public abstract bool GetCaught(int species);
|
||||
|
||||
/// <summary> Adds the Pokémon's information to the Pokédex. </summary>
|
||||
public abstract void SetDex(PKM pkm);
|
||||
|
||||
// Bulk Manipulation
|
||||
#region Overall Manipulation
|
||||
public abstract void SeenNone();
|
||||
public abstract void CaughtNone();
|
||||
|
||||
|
@ -36,8 +46,12 @@ namespace PKHeX.Core
|
|||
|
||||
public abstract void SetDexEntryAll(int species, bool shinyToo = false);
|
||||
public abstract void ClearDexEntryAll(int species);
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base class for Pokédex operations, exposing the shared structure features used by Generations 5, 6, and 7.
|
||||
/// </summary>
|
||||
public abstract class Zukan : ZukanBase
|
||||
{
|
||||
protected readonly int PokeDexLanguageFlags;
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Pokédex structure used for Generation 5 games.
|
||||
/// </summary>
|
||||
public sealed class Zukan5 : Zukan
|
||||
{
|
||||
protected override int OFS_SEEN => OFS_CAUGHT + BitSeenSize;
|
||||
|
|
|
@ -3,6 +3,9 @@ using System.Diagnostics;
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Pokédex structure used for Generation 6 games.
|
||||
/// </summary>
|
||||
public abstract class Zukan6 : Zukan
|
||||
{
|
||||
protected override int OFS_SEEN => OFS_CAUGHT + BitSeenSize;
|
||||
|
@ -178,6 +181,9 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pokédex structure used for <see cref="GameVersion.ORAS"/>.
|
||||
/// </summary>
|
||||
public sealed class Zukan6AO : Zukan6
|
||||
{
|
||||
public Zukan6AO(SAV6AO sav, int dex, int langflag) : base(sav, dex, langflag)
|
||||
|
@ -206,6 +212,9 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pokédex structure used for <see cref="GameVersion.XY"/>.
|
||||
/// </summary>
|
||||
public sealed class Zukan6XY : Zukan6
|
||||
{
|
||||
public Zukan6XY(SAV6XY sav, int dex, int langflag) : base(sav, dex, langflag)
|
||||
|
|
|
@ -5,8 +5,8 @@ using System.Diagnostics;
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Generation 7 Dex manipulator
|
||||
/// </summary>
|
||||
/// Pokédex structure used for Generation 7 games.
|
||||
/// </summary>>
|
||||
public class Zukan7 : Zukan
|
||||
{
|
||||
private const int MAGIC = 0x2F120F17;
|
||||
|
|
|
@ -3,8 +3,8 @@ using System;
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Beluga specific Dex manipulator, slightly modified from Gen7.
|
||||
/// </summary>
|
||||
/// Pokédex structure used for <see cref="GameVersion.GG"/> games, slightly modified from <see cref="Zukan7"/>.
|
||||
/// </summary>>
|
||||
public sealed class Zukan7b : Zukan7
|
||||
{
|
||||
public Zukan7b(SAV7b sav, int dex, int langflag) : base(sav, dex, langflag)
|
||||
|
|
|
@ -3,12 +3,18 @@ using System.Collections.Generic;
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
// I wish I could replace this with raw pointers via Span :)
|
||||
/// <summary>
|
||||
/// Pokédex structure used for <see cref="GameVersion.SWSH"/>.
|
||||
/// </summary>>
|
||||
public sealed class Zukan8 : ZukanBase
|
||||
{
|
||||
private readonly SCBlock Galar;
|
||||
private readonly SCBlock Rigel1;
|
||||
private readonly SCBlock Rigel2;
|
||||
|
||||
/// <summary>
|
||||
/// Reverses a Species into the component <see cref="Zukan8Index"/> information.
|
||||
/// </summary>
|
||||
public readonly IReadOnlyDictionary<int, Zukan8Index> DexLookup;
|
||||
|
||||
public Zukan8(SAV8SWSH sav, SCBlock galar, SCBlock rigel1, SCBlock rigel2) : base(sav, 0)
|
||||
|
@ -20,6 +26,9 @@ namespace PKHeX.Core
|
|||
DexLookup = GetDexLookup(PersonalTable.SWSH, revision);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks how much DLC patches have been installed by detecting if DLC blocks are present.
|
||||
/// </summary>
|
||||
public int GetRevision()
|
||||
{
|
||||
if (Rigel1.Data.Length == 0)
|
||||
|
@ -118,6 +127,7 @@ namespace PKHeX.Core
|
|||
_ => lang - 1,
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
public IList<string> GetEntryNames(IReadOnlyList<string> speciesNames)
|
||||
{
|
||||
var dex = new List<string>();
|
||||
|
@ -131,6 +141,7 @@ namespace PKHeX.Core
|
|||
dex.Sort();
|
||||
return dex;
|
||||
}
|
||||
#endif
|
||||
|
||||
#region Structure
|
||||
|
||||
|
@ -462,16 +473,19 @@ namespace PKHeX.Core
|
|||
|
||||
bool owned = GetCaught(species);
|
||||
|
||||
var g = pkm.Gender == 1 ? 1 : 0;
|
||||
var gender = pkm.Gender;
|
||||
bool shiny = pkm.IsShiny;
|
||||
var s = shiny ? 2 : 0;
|
||||
int form = pkm.Form;
|
||||
var language = pkm.Language;
|
||||
|
||||
var g = gender & 1;
|
||||
var s = shiny ? 2 : 0;
|
||||
if (species == (int)Species.Alcremie)
|
||||
{
|
||||
form *= 7;
|
||||
form += (int)((PK8)pkm).FormArgument; // alteration byte
|
||||
}
|
||||
else if (species == (int) Species.Eternatus && pkm.Form == 1)
|
||||
else if (species == (int) Species.Eternatus && form == 1)
|
||||
{
|
||||
form = 0;
|
||||
SetSeenRegion(species, 63, g | s);
|
||||
|
@ -479,7 +493,7 @@ namespace PKHeX.Core
|
|||
|
||||
SetSeenRegion(species, form, g | s);
|
||||
SetCaught(species);
|
||||
SetIsLanguageObtained(species, pkm.Language);
|
||||
SetIsLanguageObtained(species, language);
|
||||
if (!owned)
|
||||
{
|
||||
SetFormDisplayed(species, (byte)form);
|
||||
|
@ -706,10 +720,16 @@ namespace PKHeX.Core
|
|||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates which <see cref="Zukan8Type"/> block will store the entry, and at what index.
|
||||
/// </summary>
|
||||
public readonly struct Zukan8Index
|
||||
{
|
||||
/// <summary> Index that the Pokédex entry is stored at. </summary>
|
||||
public readonly int Index;
|
||||
/// <summary> Which block stores the Pokédex entry. </summary>
|
||||
public readonly Zukan8Type DexType;
|
||||
|
||||
public override string ToString() => $"{Index:000} - {DexType}";
|
||||
|
||||
public Zukan8Index(Zukan8Type dexType, int index)
|
||||
|
@ -729,12 +749,16 @@ namespace PKHeX.Core
|
|||
|
||||
public int Offset => GetSavedIndex() * Zukan8.EntrySize;
|
||||
|
||||
private const int GalarCount = 400;
|
||||
private const int Rigel1Count = 211;
|
||||
private const int Rigel2Count = 2;
|
||||
|
||||
// expects zero based indexes
|
||||
public static Zukan8Index GetFromRawIndex(int index)
|
||||
private const int GalarCount = 400; // Count within Galar dex
|
||||
private const int Rigel1Count = 211; // Count within Armor dex
|
||||
private const int Rigel2Count = 210; // Count within Crown dex
|
||||
#if DEBUG
|
||||
public const int TotalCount = GalarCount + Rigel1Count + Rigel2Count;
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Zukan8Index"/> from the absolute (overall) dex index. Don't use this method unless you're analyzing things.
|
||||
/// </summary>
|
||||
/// <param name="index">Unique Pokédex index (incremental). Should be 0-indexed.</param>
|
||||
public static Zukan8Index GetFromAbsoluteIndex(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return new Zukan8Index();
|
||||
|
@ -752,14 +776,9 @@ namespace PKHeX.Core
|
|||
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
#endif
|
||||
|
||||
public string DexPrefix => DexType switch
|
||||
{
|
||||
Zukan8Type.Galar => "O0",
|
||||
Zukan8Type.Armor => "R1",
|
||||
Zukan8Type.Crown => "R2",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
public string DexPrefix => DexType.GetZukanTypeInternalPrefix();
|
||||
|
||||
public int AbsoluteIndex => DexType switch
|
||||
{
|
||||
|
@ -802,4 +821,15 @@ namespace PKHeX.Core
|
|||
Armor,
|
||||
Crown,
|
||||
}
|
||||
|
||||
public static class Zukan8TypeExtensions
|
||||
{
|
||||
public static string GetZukanTypeInternalPrefix(this Zukan8Type type) => type switch
|
||||
{
|
||||
Zukan8Type.Galar => "O0",
|
||||
Zukan8Type.Armor => "R1",
|
||||
Zukan8Type.Crown => "R2",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
|
@ -36,27 +35,5 @@ namespace PKHeX.Core
|
|||
var httpWebResponse = httpWebRequest.GetResponse();
|
||||
return httpWebResponse.GetResponseStream();
|
||||
}
|
||||
|
||||
private static readonly Regex LatestGitTagRegex = new("\\\"tag_name\"\\s*\\:\\s*\\\"([0-9]+\\.[0-9]+\\.[0-9]+)\\\""); // Match `"tag_name": "18.12.02"`. Group 1 is `18.12.02`
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest version of PKHeX according to the Github API
|
||||
/// </summary>
|
||||
/// <returns>A version representing the latest available version of PKHeX, or null if the latest version could not be determined</returns>
|
||||
public static Version? GetLatestPKHeXVersion()
|
||||
{
|
||||
const string apiEndpoint = "https://api.github.com/repos/kwsch/pkhex/releases/latest";
|
||||
var responseJson = GetStringFromURL(apiEndpoint);
|
||||
if (string.IsNullOrEmpty(responseJson))
|
||||
return null;
|
||||
|
||||
// Using a regex to get the tag to avoid importing an entire JSON parsing library
|
||||
var tagMatch = LatestGitTagRegex.Match(responseJson);
|
||||
if (!tagMatch.Success)
|
||||
return null;
|
||||
|
||||
var tagString = tagMatch.Groups[1].Value;
|
||||
return !Version.TryParse(tagString, out var latestVersion) ? null : latestVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
30
PKHeX.Core/Util/UpdateUtil.cs
Normal file
30
PKHeX.Core/Util/UpdateUtil.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class UpdateUtil
|
||||
{
|
||||
private static readonly Regex LatestGitTagRegex = new("\\\"tag_name\"\\s*\\:\\s*\\\"([0-9]+\\.[0-9]+\\.[0-9]+)\\\""); // Match `"tag_name": "18.12.02"`. Group 1 is `18.12.02`
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest version of PKHeX according to the Github API
|
||||
/// </summary>
|
||||
/// <returns>A version representing the latest available version of PKHeX, or null if the latest version could not be determined</returns>
|
||||
public static Version? GetLatestPKHeXVersion()
|
||||
{
|
||||
const string apiEndpoint = "https://api.github.com/repos/kwsch/pkhex/releases/latest";
|
||||
var responseJson = NetUtil.GetStringFromURL(apiEndpoint);
|
||||
if (string.IsNullOrEmpty(responseJson))
|
||||
return null;
|
||||
|
||||
// Using a regex to get the tag to avoid importing an entire JSON parsing library
|
||||
var tagMatch = LatestGitTagRegex.Match(responseJson);
|
||||
if (!tagMatch.Success)
|
||||
return null;
|
||||
|
||||
var tagString = tagMatch.Groups[1].Value;
|
||||
return !Version.TryParse(tagString, out var latestVersion) ? null : latestVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -236,7 +236,7 @@ namespace PKHeX.WinForms
|
|||
{
|
||||
Version? latestVersion;
|
||||
// User might not be connected to the internet or with a flaky connection.
|
||||
try { latestVersion = NetUtil.GetLatestPKHeXVersion(); }
|
||||
try { latestVersion = UpdateUtil.GetLatestPKHeXVersion(); }
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
catch (Exception ex)
|
||||
#pragma warning restore CA1031 // Do not catch general exception types
|
||||
|
|
Loading…
Add table
Reference in a new issue