using System; using static PKHeX.Core.Species; namespace PKHeX.Core; /// /// Logic for relating Forms and the Held Item. /// public static class FormItem { private static ReadOnlySpan Arceus_PlateIDs => new ushort[] { 303, 306, 304, 305, 309, 308, 310, 313, 298, 299, 301, 300, 307, 302, 311, 312, 644 }; private static ReadOnlySpan Arceus_ZCrystal => new ushort[] { 782, 785, 783, 784, 788, 787, 789, 792, 777, 778, 780, 779, 786, 781, 790, 791, 793 }; /// /// Gets the form for based on the held item. /// /// Held Item /// Generation/Format of the entity /// Form ID public static byte GetFormArceus(int item, int format) => item switch { (>= 777 and <= 793) => GetFormArceusZCrystal(item), (>= 298 and <= 313) or 644 => GetFormArceusPlate(item, format), _ => 0, }; /// /// Gets the form for based on the held item (Generation 7 Z-Crystals). /// /// Held Item /// Form ID public static byte GetFormArceusZCrystal(int item) => (byte)(Arceus_ZCrystal.IndexOf((ushort)item) + 1); /// /// Gets the held item for based on the form (Excluding Generation 7 Z-Crystals). /// /// Held Item /// Generation/Format of the entity /// Held Item public static byte GetFormArceusPlate(int item, int format) { byte form = (byte)(Arceus_PlateIDs.IndexOf((ushort)item) + 1); if (format != 4) // No need to consider Curse type return form; if (form < 9) return form; return ++form; // ??? type Form shifts everything by 1 } /// /// Gets the held item for based on the form. /// /// Form ID /// Generation/Format of the entity /// Held Item public static ushort GetItemArceus(byte form, int format) { var index = form - 1; if (format == 4 && form > 8) index--; // ignore curse type var arr = Arceus_PlateIDs; if ((uint)index >= arr.Length) return 0; return arr[index]; } /// /// Gets the form for based on the held item. /// /// Held Item /// Form ID public static byte GetFormSilvally(int item) { if (item is >= 904 and <= 920) return (byte)(item - 903); return 0; } /// /// Gets the held item for based on the form. /// /// Form ID /// Held Item public static ushort GetItemSilvally(byte form) { if (form is >= 1 and <= 17) return (ushort)(form + 903); return 0; } /// /// Gets the form for based on the held item. /// /// Held Item /// Form ID public static byte GetFormGenesect(int item) { if (item is >= 116 and <= 119) return (byte)(item - 115); return 0; } /// /// Gets the held item for based on the form. /// /// Form ID /// Held Item public static ushort GetItemGenesect(byte form) { if (form is >= 1 and <= 4) return (ushort)(form + 115); return 0; } /// /// Gets the form for based on the held item. /// /// Held Item /// Form ID public static byte GetFormOgerpon(int item) => item switch { 2407 => 1, // Wellspring Mask 2408 => 2, // Hearthflame Mask 2406 => 3, // Cornerstone Mask _ => 0, // Teal Mask }; /// /// Gets the held item for based on the form. /// /// Form ID /// Held Item public static ushort GetItemOgerpon(byte form) => form switch { 1 => 2407, // Wellspring Mask 2 => 2408, // Hearthflame Mask 3 => 2406, // Cornerstone Mask _ => 0, // Teal Mask (no held item required) }; /// /// Gets the held item for based on the form. /// /// Entity Species /// Form ID /// 0 if no held item is required public static ushort GetItem(ushort species, byte form) => species switch { (ushort)Arceus => GetItemArceus(form, 8), (ushort)Silvally => GetItemSilvally(form), (ushort)Genesect => GetItemGenesect(form), (ushort)Ogerpon => GetItemOgerpon(form), _ => 0, }; /// /// Gets the form for based on the held item. /// /// Entity Species /// Held Item /// Generation/Format of the entity /// Expected Form ID /// True if the form is required public static bool TryGetForm(ushort species, int item, int format, out byte form) { switch (species) { case (ushort)Arceus: form = GetFormArceus(item, format); return true; case (ushort)Silvally: form = GetFormSilvally(item); return true; case (ushort)Genesect: form = GetFormGenesect(item); return true; case (ushort)Ogerpon: form = GetFormOgerpon(item); return true; default: form = 0; return false; } } }