using System;
using System.Collections.Generic;
using System.Linq;
using static PKHeX.Core.GameVersion;
namespace PKHeX.Core;
///
/// Utility class for logic.
///
public static class GameUtil
{
///
/// All possible values a can have.
///
/// Ordered roughly by most recent games first.
public static readonly GameVersion[] GameVersions = GetValidGameVersions();
private static GameVersion[] GetValidGameVersions()
{
var all = (GameVersion[])Enum.GetValues(typeof(GameVersion));
var valid = Array.FindAll(all, IsValidSavedVersion);
Array.Reverse(valid);
return valid;
}
///
/// Indicates if the value is a value used by the games or is an aggregate indicator.
///
/// Game to check
public static bool IsValidSavedVersion(this GameVersion game) => game is > 0 and <= HighestGameID;
///
/// Most recent game ID utilized by official games.
///
internal const GameVersion HighestGameID = RB - 1;
/// Determines the Version Grouping of an input Version ID
/// Version of which to determine the group
/// Version Group Identifier or Invalid if type cannot be determined.
public static GameVersion GetMetLocationVersionGroup(GameVersion version) => version switch
{
// Side games
CXD => CXD,
GO => GO,
// VC Transfers
RD or BU or YW or GN or GD or SI or C => USUM,
// Gen2 -- PK2
GS or GSC => GSC,
// Gen3
R or S => RS,
E => E,
FR or LG => FR,
// Gen4
D or P => DP,
Pt => Pt,
HG or SS => HGSS,
// Gen5
B or W => BW,
B2 or W2 => B2W2,
// Gen6
X or Y => XY,
OR or AS => ORAS,
// Gen7
SN or MN => SM,
US or UM => USUM,
GP or GE => GG,
// Gen8
SW or SH => SWSH,
BD or SP => BDSP,
PLA => PLA,
// Gen9
SL or VL => SV,
_ => Invalid,
};
///
/// Gets a Version ID from the end of that Generation
///
/// Generation ID
/// Version ID from requested generation. If none, return .
public static GameVersion GetVersion(byte generation) => generation switch
{
1 => RBY,
2 => C,
3 => E,
4 => SS,
5 => W2,
6 => AS,
7 => UM,
8 => SH,
9 => VL,
_ => Invalid,
};
///
/// Gets the Generation the belongs to.
///
/// Game to retrieve the generation for
/// Generation ID
public static byte GetGeneration(this GameVersion game)
{
if (Gen1.Contains(game)) return 1;
if (Gen2.Contains(game)) return 2;
if (Gen3.Contains(game)) return 3;
if (Gen4.Contains(game)) return 4;
if (Gen5.Contains(game)) return 5;
if (Gen6.Contains(game)) return 6;
if (Gen7.Contains(game)) return 7;
if (Gen7b.Contains(game)) return 7;
if (Gen8.Contains(game)) return 8;
if (Gen9.Contains(game)) return 9;
return 0;
}
///
/// Gets the Generation the belongs to.
///
/// Game to retrieve the generation for
/// Generation ID
public static ushort GetMaxSpeciesID(this GameVersion game)
{
if (Gen1.Contains(game)) return Legal.MaxSpeciesID_1;
if (Gen2.Contains(game)) return Legal.MaxSpeciesID_2;
if (Gen3.Contains(game)) return Legal.MaxSpeciesID_3;
if (Gen4.Contains(game)) return Legal.MaxSpeciesID_4;
if (Gen5.Contains(game)) return Legal.MaxSpeciesID_5;
if (Gen6.Contains(game)) return Legal.MaxSpeciesID_6;
if (Gen7b.Contains(game)) return Legal.MaxSpeciesID_7b;
if (Gen7.Contains(game))
{
if (SM.Contains(game))
return Legal.MaxSpeciesID_7;
if (USUM.Contains(game))
return Legal.MaxSpeciesID_7_USUM;
return Legal.MaxSpeciesID_7_USUM;
}
if (PLA == game) return Legal.MaxSpeciesID_8a;
if (BDSP.Contains(game)) return Legal.MaxSpeciesID_8b;
if (Gen8.Contains(game)) return Legal.MaxSpeciesID_8;
if (Gen9.Contains(game)) return Legal.MaxSpeciesID_9;
return 0;
}
///
/// Checks if the version (or subset versions) is equivalent to .
///
/// Version (set)
/// Individual version
public static bool Contains(this GameVersion g1, int g2) => g1.Contains((GameVersion) g2);
///
/// Checks if the version (or subset versions) is equivalent to .
///
/// Version (set)
/// Individual version
public static bool Contains(this GameVersion g1, GameVersion g2)
{
if (g1 == g2 || g1 == Any)
return true;
if (g1.IsValidSavedVersion())
return false;
return g1.ContainsFromLumped(g2);
}
public static bool ContainsFromLumped(this GameVersion lump, GameVersion version) => lump switch
{
RB => version is RD or BU or GN,
RBY => version is RD or BU or GN or YW or RB,
Stadium => version is RD or BU or GN or YW or RB or RBY,
StadiumJ => version is RD or BU or GN or YW or RB or RBY,
Gen1 => version is RD or BU or GN or YW or RB or RBY or Stadium,
GS => version is GD or SI,
GSC => version is GD or SI or C or GS,
Stadium2 => version is GD or SI or C or GS or GSC,
Gen2 => version is GD or SI or C or GS or GSC or Stadium2,
RS => version is R or S,
RSE => version is R or S or E or RS,
FRLG => version is FR or LG,
RSBOX => version is R or S or E or FR or LG,
Gen3 => version is R or S or E or FR or LG or CXD or RSBOX or RS or RSE or FRLG,
COLO => version is CXD,
XD => version is CXD,
DP => version is D or P,
HGSS => version is HG or SS,
DPPt => version is D or P or Pt or DP,
BATREV => version is D or P or Pt or HG or SS,
Gen4 => version is D or P or Pt or HG or SS or BATREV or DP or HGSS or DPPt,
BW => version is B or W,
B2W2 => version is B2 or W2,
Gen5 => version is B or W or B2 or W2 or BW or B2W2,
XY => version is X or Y,
ORAS => version is OR or AS,
Gen6 => version is X or Y or OR or AS or XY or ORAS,
SM => version is SN or MN,
USUM => version is US or UM,
Gen7 => version is SN or MN or US or UM or SM or USUM,
GG => version is GP or GE,
Gen7b => version is GP or GE or GO,
SWSH => version is SW or SH,
BDSP => version is BD or SP,
Gen8 => version is SW or SH or BD or SP or SWSH or BDSP or PLA,
SV => version is SL or VL,
Gen9 => version is SL or VL or SV,
_ => false,
};
///
/// List of possible values within the provided .
///
/// Generation to look within
///
public static GameVersion[] GetVersionsInGeneration(byte generation, GameVersion version)
{
if (Gen7b.Contains(version))
return [GO, GP, GE];
return Array.FindAll(GameVersions, z => z.GetGeneration() == generation);
}
///
/// List of possible values within the provided criteria.
///
/// Criteria for retrieving versions
/// Generation format minimum (necessary for the CXD/Gen4 swap etc.)
public static IEnumerable GetVersionsWithinRange(IGameValueLimit obj, byte generation = 0)
{
var max = obj.MaxGameID;
if (max == Legal.MaxGameID_7b) // edge case
return [GO, GP, GE];
var versions = GameVersions
.Where(version => obj.MinGameID <= version && version <= max);
if (generation == 0)
return versions;
if (max == Legal.MaxGameID_7 && generation == 7)
versions = versions.Where(version => version != GO);
// HOME allows up-reach to Gen9
if (generation >= 8)
generation = 9;
return versions.Where(version => version.GetGeneration() <= generation);
}
///
/// Finds all values within the .
///
public static GameVersion[] GetVersionsWithinRange(this GameVersion lump, GameVersion[] source) =>
Array.FindAll(source, z => lump.Contains(z));
}