mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-04 16:36:30 -05:00
294 lines
11 KiB
C#
294 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using static PKHeX.Core.GameVersion;
|
|
|
|
namespace PKHeX.Core;
|
|
|
|
/// <summary>
|
|
/// Utility class for <see cref="GameVersion"/> logic.
|
|
/// </summary>
|
|
public static class GameUtil
|
|
{
|
|
/// <summary>
|
|
/// All possible <see cref="GameVersion"/> values a <see cref="PKM.Version"/> can have.
|
|
/// </summary>
|
|
/// <remarks>Ordered roughly by most recent games first.</remarks>
|
|
public static readonly GameVersion[] GameVersions = GetValidGameVersions();
|
|
|
|
private static GameVersion[] GetValidGameVersions()
|
|
{
|
|
var all = Enum.GetValues<GameVersion>();
|
|
var valid = Array.FindAll(all, IsValidSavedVersion);
|
|
Array.Reverse(valid);
|
|
return valid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Most recent game ID utilized by official games.
|
|
/// </summary>
|
|
internal const GameVersion HighestGameID = RB - 1;
|
|
|
|
/// <summary>Determines the Version Grouping of an input Version ID</summary>
|
|
/// <param name="version">Version of which to determine the group</param>
|
|
/// <returns>Version Group Identifier or Invalid if type cannot be determined.</returns>
|
|
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,
|
|
ZA => ZA,
|
|
|
|
CP => CP, // TODO: Champions
|
|
|
|
_ => Invalid,
|
|
};
|
|
|
|
/// <summary>
|
|
/// Gets a Version ID from the end of that Generation
|
|
/// </summary>
|
|
/// <param name="generation">Generation ID</param>
|
|
/// <returns>Version ID from requested generation. If none, return <see cref="Invalid"/>.</returns>
|
|
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,
|
|
};
|
|
|
|
extension(GameVersion version)
|
|
{
|
|
/// <summary>
|
|
/// Gets the Generation the <see cref="GameVersion"/> belongs to.
|
|
/// </summary>
|
|
/// <returns>Generation ID</returns>
|
|
public byte Generation => version.GetContextInternal().Generation;
|
|
|
|
private EntityContext GetContextInternal()
|
|
{
|
|
if (version.IsValidSavedVersion())
|
|
return version.GetContextFromSaved();
|
|
|
|
if (Gen1.Contains(version)) return EntityContext.Gen1;
|
|
if (Gen2.Contains(version)) return EntityContext.Gen2;
|
|
if (Gen3.Contains(version)) return EntityContext.Gen3;
|
|
if (Gen4.Contains(version)) return EntityContext.Gen4;
|
|
if (Gen5.Contains(version)) return EntityContext.Gen5;
|
|
if (Gen6.Contains(version)) return EntityContext.Gen6;
|
|
if (Gen7.Contains(version)) return EntityContext.Gen7;
|
|
if (Gen7b.Contains(version)) return EntityContext.Gen7b;
|
|
if (SWSH.Contains(version)) return EntityContext.Gen8;
|
|
if (BDSP.Contains(version)) return EntityContext.Gen8b;
|
|
if (SV.Contains(version)) return EntityContext.Gen9;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indicates if the <see cref="GameVersion"/> value is a value used by the games or is an aggregate indicator.
|
|
/// </summary>
|
|
public bool IsValidSavedVersion() => version is > 0 and <= HighestGameID;
|
|
|
|
public EntityContext GetContextFromSaved() => version switch
|
|
{
|
|
S or R or E or FR or LG or CXD => EntityContext.Gen3,
|
|
D or P or Pt or HG or SS or BATREV => EntityContext.Gen4,
|
|
B or W or B2 or W2 => EntityContext.Gen5,
|
|
X or Y or AS or OR => EntityContext.Gen6,
|
|
SN or MN or US or UM => EntityContext.Gen7,
|
|
RD or GN or BU or YW => EntityContext.Gen1,
|
|
GD or SI or C => EntityContext.Gen2,
|
|
GP or GE => EntityContext.Gen7b,
|
|
PLA => EntityContext.Gen8a,
|
|
BD or SP => EntityContext.Gen8b,
|
|
SW or SH => EntityContext.Gen8,
|
|
SL or VL => EntityContext.Gen9,
|
|
ZA => EntityContext.Gen9a,
|
|
_ => 0
|
|
};
|
|
|
|
/// <summary>
|
|
/// Gets the Generation the <see cref="GameVersion"/> belongs to.
|
|
/// </summary>
|
|
/// <returns>Generation ID</returns>
|
|
public ushort GetMaxSpeciesID() => version switch
|
|
{
|
|
RD or GN or BU or YW => Legal.MaxSpeciesID_1,
|
|
GD or SI or C => Legal.MaxSpeciesID_2,
|
|
S or R or E or FR or LG or CXD => Legal.MaxSpeciesID_3,
|
|
D or P or Pt or HG or SS => Legal.MaxSpeciesID_4,
|
|
B or W or B2 or W2 => Legal.MaxSpeciesID_5,
|
|
X or Y or AS or OR => Legal.MaxSpeciesID_6,
|
|
GP or GE => Legal.MaxSpeciesID_7b,
|
|
SN or MN => Legal.MaxSpeciesID_7,
|
|
US or UM => Legal.MaxSpeciesID_7_USUM,
|
|
PLA => Legal.MaxSpeciesID_8a,
|
|
BD or SP => Legal.MaxSpeciesID_8b,
|
|
SW or SH => Legal.MaxSpeciesID_8,
|
|
SL or VL => Legal.MaxSpeciesID_9,
|
|
ZA => Legal.MaxSpeciesID_9a,
|
|
CP => Legal.MaxSpeciesID_9, // TODO: Champions
|
|
_ => 0
|
|
};
|
|
|
|
/// <summary>
|
|
/// Checks if the <see cref="version"/> version (or subset versions) is equivalent to <see cref="g2"/>.
|
|
/// </summary>
|
|
/// <param name="g2">Individual version</param>
|
|
public bool Contains(GameVersion g2)
|
|
{
|
|
if (version == g2 || version == Any)
|
|
return true;
|
|
if (version.IsValidSavedVersion())
|
|
return false;
|
|
return version.ContainsFromLumped(g2);
|
|
}
|
|
|
|
public bool IsGen1() => version is RD or GN or BU or YW;
|
|
public bool IsGen2() => version is GD or SI or C;
|
|
public bool IsGen3() => version is S or R or E or FR or LG or CXD;
|
|
public bool IsGen4() => version is HG or SS or D or P or Pt;
|
|
public bool IsGen5() => version is W or B or W2 or B2;
|
|
public bool IsGen6() => version is X or Y or AS or OR;
|
|
public bool IsGen7() => version is SN or MN or US or UM;
|
|
public bool IsGen7b() => version is GP or GE;
|
|
public bool IsGen8() => version is SW or SH or PLA or BD or SP;
|
|
public bool IsGen9() => version is SL or VL or ZA;
|
|
|
|
/// <summary>
|
|
/// Checks if the <see cref="version"/> version is the lump of the requested saved <see cref="version1"/>.
|
|
/// </summary>
|
|
public bool ContainsFromLumped(GameVersion version1) => version switch
|
|
{
|
|
RB => version1 is RD or BU or GN,
|
|
RBY => version1 is RD or BU or GN or YW or RB,
|
|
Stadium => version1 is RD or BU or GN or YW or RB or RBY,
|
|
StadiumJ => version1 is RD or BU or GN or YW or RB or RBY,
|
|
Gen1 => version1 is RD or BU or GN or YW or RB or RBY or Stadium,
|
|
|
|
GS => version1 is GD or SI,
|
|
GSC => version1 is GD or SI or C or GS,
|
|
Stadium2 => version1 is GD or SI or C or GS or GSC,
|
|
Gen2 => version1 is GD or SI or C or GS or GSC or Stadium2,
|
|
|
|
RS => version1 is R or S,
|
|
RSE => version1 is R or S or E or RS,
|
|
FRLG => version1 is FR or LG,
|
|
EFL => version1 is E or FR or LG,
|
|
RSBOX => version1 is R or S or E or FR or LG,
|
|
Gen3 => version1 is R or S or E or FR or LG or CXD or RSBOX or RS or RSE or FRLG,
|
|
COLO => version1 is CXD,
|
|
XD => version1 is CXD,
|
|
|
|
DP => version1 is D or P,
|
|
HGSS => version1 is HG or SS,
|
|
DPPt => version1 is D or P or Pt or DP,
|
|
Gen4 => version1 is D or P or Pt or HG or SS or BATREV or DP or HGSS or DPPt,
|
|
|
|
BW => version1 is B or W,
|
|
B2W2 => version1 is B2 or W2,
|
|
Gen5 => version1 is B or W or B2 or W2 or BW or B2W2,
|
|
|
|
XY => version1 is X or Y,
|
|
ORAS => version1 is OR or AS,
|
|
Gen6 => version1 is X or Y or OR or AS or XY or ORAS,
|
|
|
|
SM => version1 is SN or MN,
|
|
USUM => version1 is US or UM,
|
|
Gen7 => version1 is SN or MN or US or UM or SM or USUM,
|
|
|
|
GG => version1 is GP or GE,
|
|
Gen7b => version1 is GP or GE or GO or GG,
|
|
|
|
SWSH => version1 is SW or SH,
|
|
BDSP => version1 is BD or SP,
|
|
Gen8 => version1 is SW or SH or BD or SP or SWSH or BDSP or PLA,
|
|
|
|
SV => version1 is SL or VL,
|
|
Gen9 => version1 is SL or VL or SV or ZA,
|
|
|
|
_ => false,
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// List of possible <see cref="GameVersion"/> values within the provided <see cref="context"/>.
|
|
/// </summary>
|
|
/// <param name="context">Generation to look within</param>
|
|
/// <param name="version">Entity version</param>
|
|
public static GameVersion[] GetVersionsInGeneration(EntityContext context, GameVersion version)
|
|
{
|
|
if (context is EntityContext.Gen7b)
|
|
return [GO, GP, GE];
|
|
return Array.FindAll(GameVersions, z => z.Context == context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// List of possible <see cref="GameVersion"/> values within the provided <see cref="IGameValueLimit"/> criteria.
|
|
/// </summary>
|
|
/// <param name="obj">Criteria for retrieving versions</param>
|
|
/// <param name="context">Generation format minimum (necessary for the CXD/Gen4 swap etc.)</param>
|
|
public static IEnumerable<GameVersion> GetVersionsWithinRange(IGameValueLimit obj, EntityContext context = 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 (max != BATREV)
|
|
versions = versions.Where(static version => version != BATREV);
|
|
if (context == 0)
|
|
return versions;
|
|
if (max == Legal.MaxGameID_7 && context == EntityContext.Gen7)
|
|
versions = versions.Where(static version => version != GO);
|
|
|
|
// HOME allows up-reach to Gen9
|
|
if (context.IsEraHOME)
|
|
return versions;
|
|
return versions.Where(version => version.Generation <= context.Generation);
|
|
}
|
|
}
|