using System; using static PKHeX.Core.GameVersion; namespace PKHeX.Core; /// /// Logic for SW/SH met locations from HOME. /// public static class LocationsHOME { // 60000 - (version - PLA) private const int RemapCount = 5; // Count of future game version IDs that can transfer back into SW/SH. public const ushort SHVL = 59996; // VL traded to (SW)SH public const ushort SWSL = 59997; // SL traded to SW(SH) public const ushort SHSP = 59998; // SP traded to (SW)SH public const ushort SWBD = 59999; // BD traded to SW(SH) public const ushort SWLA = 60000; // PLA traded to SW(SH) public const ushort SWSHEgg = 65534; // -2 = 8bNone-1.. /// /// Gets the external entity version needs to be remapped into a location for SW/SH. /// /// /// True if a known remap exists. public static bool IsVersionRemapNeeded(GameVersion version) => GetRemapIndex(version) < RemapCount; private static int GetRemapIndex(GameVersion version) => version - PLA; /// /// Checks if the SW/SH-context Met Location is one of the remapped HOME locations. /// public static bool IsLocationSWSH(ushort met) => met switch { SHVL or SWSL or SHSP or SWBD or SWLA => true, _ => false, }; /// /// Checks if the SW/SH-context Egg Location is valid with respect to the location. /// public static bool IsLocationSWSHEgg(GameVersion version, ushort met, int egg, ushort original) { if (original > SWLA && egg == SWSHEgg) return true; // >60000 can be reset to Link Trade (30001), then altered differently. var expect = GetMetSWSH(original, version); return expect == met && expect == egg; } /// /// Gets the SW/SH-context Egg Location when an external entity from the input resides in SW/SH. /// public static ushort GetLocationSWSHEgg(GameVersion version, ushort egg) { if (egg == 0) return 0; if (egg > SWLA) return SWSHEgg; // >60000 can be reset to Link Trade (30001), then altered differently. return GetMetSWSH(egg, version); } /// /// Gets the SW/SH-context when an external entity from the input resides in SW/SH. /// public static GameVersion GetVersionSWSH(GameVersion version) => version switch { GameVersion.PLA => GameVersion.SW, GameVersion.BD => GameVersion.SW, GameVersion.SP => GameVersion.SH, GameVersion.SL => GameVersion.SW, GameVersion.VL => GameVersion.SH, _ => version, }; /// /// Gets the SW/SH-context Met Location when an external entity from the input resides in SW/SH. /// public static ushort GetMetSWSH(ushort loc, GameVersion version) => version switch { GameVersion.PLA => SWLA, GameVersion.BD => SWBD, GameVersion.SP => SHSP, GameVersion.SL => SWSL, GameVersion.VL => SHVL, _ => loc, }; public static GameVersion GetVersionSWSHOriginal(ushort loc) => loc switch { SWLA => GameVersion.PLA, SWBD => GameVersion.BD, SHSP => GameVersion.SP, SWSL => GameVersion.SL, SHVL => GameVersion.VL, _ => GameVersion.SW, }; /// /// Checks if the met location is a valid location for the input . /// /// Relevant when an entity from BD/SP is transferred to SW/SH. public static bool IsValidMetBDSP(ushort loc, GameVersion version) => loc switch { SHSP when version == SH => true, SWBD when version == SW => true, _ => false, }; /// /// Checks if the met location is a valid location for the input . /// /// Relevant when an entity from S/V is transferred to SW/SH. public static bool IsValidMetSV(ushort loc, GameVersion version) => loc switch { SHVL when version == SH => true, SWSL when version == SW => true, _ => false, }; /// /// Checks if the location is (potentially) remapped based on visitation options. /// /// Relevant when a side data yields SW/SH side data with a higher priority than the original (by version) side data. /// Original context /// Current context public static LocationRemapState GetRemapState(EntityContext original, EntityContext current) { if (current == original) return LocationRemapState.Original; if (current == EntityContext.Gen8) return LocationRemapState.Remapped; return original.Generation() switch { < 8 => LocationRemapState.Original, 8 => LocationRemapState.Either, _ => current is (EntityContext.Gen8a or EntityContext.Gen8b) // down ? LocationRemapState.Either : LocationRemapState.Original, }; } public static bool IsMatchLocation(EntityContext original, EntityContext current, ushort met, int expect, GameVersion version) { var state = GetRemapState(original, current); return state switch { LocationRemapState.Original => met == expect, LocationRemapState.Remapped => met == GetMetSWSH((ushort)expect, version), LocationRemapState.Either => met == expect || met == GetMetSWSH((ushort)expect, version), _ => false, }; } } [Flags] public enum LocationRemapState { None, Original = 1 << 0, Remapped = 1 << 1, Either = Original | Remapped, }