diff --git a/PKHeX.Core/Game/GameUtil.cs b/PKHeX.Core/Game/GameUtil.cs
index 897707880..af6d55817 100644
--- a/PKHeX.Core/Game/GameUtil.cs
+++ b/PKHeX.Core/Game/GameUtil.cs
@@ -1,5 +1,7 @@
using System;
+using System.Collections.Generic;
using System.Linq;
+using static PKHeX.Core.GameVersion;
namespace PKHeX.Core
{
@@ -8,6 +10,17 @@ namespace PKHeX.Core
///
public static class GameUtil
{
+ ///
+ /// List of possible values a can have.
+ ///
+ public static readonly GameVersion[] GameVersions = ((GameVersion[])Enum.GetValues(typeof(GameVersion))).Where(z => z < RB && z > 0).Reverse().ToArray();
+
+ ///
+ /// 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) => 0 < game && game <= RB;
+
/// 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.
@@ -15,73 +28,56 @@ namespace PKHeX.Core
{
switch (Version)
{
- case GameVersion.CXD:
- return GameVersion.CXD;
+ // Sidegame
+ case CXD:
+ return CXD;
+ case GO:
+ return GO;
- case GameVersion.GO:
- return GameVersion.GO;
+ // Gen1
+ case RBY: case RD: case BU: case YW: case GN:
+ return RBY;
- case GameVersion.RBY:
- case GameVersion.RD:
- case GameVersion.BU:
- case GameVersion.YW:
- case GameVersion.GN:
- return GameVersion.RBY;
+ // Gen2
+ case GS: case GD: case SV: case C:
+ return GSC;
- case GameVersion.GS:
- case GameVersion.GD:
- case GameVersion.SV:
- case GameVersion.C:
- return GameVersion.GSC;
+ // Gen3
+ case R: case S:
+ return RS;
+ case E:
+ return E;
+ case FR: case LG:
+ return FR;
- case GameVersion.R:
- case GameVersion.S:
- return GameVersion.RS;
+ // Gen4
+ case D: case P:
+ return DP;
+ case Pt:
+ return Pt;
+ case HG: case SS:
+ return HGSS;
- case GameVersion.E:
- return GameVersion.E;
+ // Gen5
+ case B: case W:
+ return BW;
+ case B2: case W2:
+ return B2W2;
- case GameVersion.FR:
- case GameVersion.LG:
- return GameVersion.FR;
+ // Gen6
+ case X: case Y:
+ return XY;
+ case OR: case AS:
+ return ORAS;
- case GameVersion.D:
- case GameVersion.P:
- return GameVersion.DP;
-
- case GameVersion.Pt:
- return GameVersion.Pt;
-
- case GameVersion.HG:
- case GameVersion.SS:
- return GameVersion.HGSS;
-
- case GameVersion.B:
- case GameVersion.W:
- return GameVersion.BW;
-
- case GameVersion.B2:
- case GameVersion.W2:
- return GameVersion.B2W2;
-
- case GameVersion.X:
- case GameVersion.Y:
- return GameVersion.XY;
-
- case GameVersion.OR:
- case GameVersion.AS:
- return GameVersion.ORAS;
-
- case GameVersion.SN:
- case GameVersion.MN:
- return GameVersion.SM;
-
- case GameVersion.US:
- case GameVersion.UM:
- return GameVersion.USUM;
+ // Gen7
+ case SN: case MN:
+ return SM;
+ case US: case UM:
+ return USUM;
default:
- return GameVersion.Invalid;
+ return Invalid;
}
}
@@ -94,59 +90,127 @@ namespace PKHeX.Core
{
switch (generation)
{
- case 1: return GameVersion.RBY;
- case 2: return GameVersion.C;
- case 3: return GameVersion.E;
- case 4: return GameVersion.SS;
- case 5: return GameVersion.W2;
- case 6: return GameVersion.AS;
- case 7: return GameVersion.UM;
+ case 1: return RBY;
+ case 2: return C;
+ case 3: return E;
+ case 4: return SS;
+ case 5: return W2;
+ case 6: return AS;
+ case 7: return UM;
default:
- return GameVersion.Invalid;
- }
- }
- public static int GetGeneration(GameVersion game)
- {
- game = GetMetLocationVersionGroup(game); // get group
- switch (game)
- {
- default: return -1;
-
- case GameVersion.RBY: return 1;
- case GameVersion.GSC: return 2;
-
- case GameVersion.CXD:
- case GameVersion.RS: case GameVersion.E:
- case GameVersion.FR: case GameVersion.LG:
- return 3;
-
- case GameVersion.DP: case GameVersion.Pt:
- case GameVersion.HGSS:
- return 4;
-
- case GameVersion.BW:
- case GameVersion.B2W2:
- return 5;
-
- case GameVersion.XY:
- case GameVersion.ORAS:
- return 6;
-
- case GameVersion.SM:
- case GameVersion.USUM:
- return 7;
+ return Invalid;
}
}
///
- /// List of possible values a can have.
+ /// Gets the Generation the belongs to.
///
- public static readonly GameVersion[] GameVersions = ((GameVersion[])Enum.GetValues(typeof(GameVersion))).Where(z => z < GameVersion.RB && z > 0).Reverse().ToArray();
+ /// Game to retrieve the generation for
+ /// Generation ID
+ public static int 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;
+ return -1;
+ }
+
+
+ ///
+ /// 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;
+
+ switch (g1)
+ {
+ case RB:
+ return g2 == RD || g2 == BU || g2 == GN;
+ case RBY:
+ return RB.Contains(g2) || g2 == YW;
+ case Gen1:
+ return RBY.Contains(g2) || g2 == Stadium || g2 == EventsGBGen1 || g2 == VCEvents;
+ case Stadium:
+ case EventsGBGen1:
+ case VCEvents:
+ goto case RBY;
+
+ case GS: return g2 == GD || g2 == SV;
+ case GSC:
+ return GS.Contains(g2) || g2 == C;
+ case Gen2:
+ return GSC.Contains(g2) || g2 == Stadium2 || g2 == EventsGBGen2;
+ case Stadium2:
+ case EventsGBGen2:
+ goto case GSC;
+ case GBCartEraOnly:
+ return g2 == Stadium || g2 == Stadium2 || g2 == EventsGBGen1 || g2 == EventsGBGen2;
+
+ case RS: return g2 == R || g2 == S;
+ case RSE:
+ return RS.Contains(g2) || g2 == E;
+ case FRLG: return g2 == FR || g2 == LG;
+ case COLO:
+ case XD: return g2 == CXD;
+ case CXD: return g2 == COLO || g2 == XD;
+ case RSBOX: return RS.Contains(g2) || g2 == E || FRLG.Contains(g2);
+ case Gen3:
+ return RSE.Contains(g2) || FRLG.Contains(g2) || CXD.Contains(g2) || g2 == RSBOX;
+
+ case DP: return g2 == D || g2 == P;
+ case HGSS: return g2 == HG || g2 == SS;
+ case DPPt:
+ return DP.Contains(g2) || g2 == Pt;
+ case BATREV: return DP.Contains(g2) || g2 == Pt || HGSS.Contains(g2);
+ case Gen4:
+ return DPPt.Contains(g2) || HGSS.Contains(g2) || g2 == BATREV;
+
+ case BW: return g2 == B || g2 == W;
+ case B2W2: return g2 == B2 || g2 == W2;
+ case Gen5:
+ return BW.Contains(g2) || B2W2.Contains(g2);
+
+ case XY: return g2 == X || g2 == Y;
+ case ORAS: return g2 == OR || g2 == AS;
+ case Gen6:
+ return XY.Contains(g2) || ORAS.Contains(g2);
+
+ case SM:
+ return g2 == SN || g2 == MN;
+ case USUM:
+ return g2 == US || g2 == UM;
+ case Gen7:
+ return SM.Contains(g2) || USUM.Contains(g2);
+
+ default: return false;
+ }
+ }
///
/// List of possible values within the provided .
///
/// Generation to look within
public static GameVersion[] GetVersionsInGeneration(int generation) => GameVersions.Where(z => z.GetGeneration() == generation).ToArray();
+
+ ///
+ /// 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, int generation = -1)
+ {
+ var vers = GameVersions.Where(z => z >= (GameVersion)obj.MinGameID && z <= (GameVersion)obj.MaxGameID);
+ if (generation == -1)
+ return vers;
+ return vers.Where(z => z.GetGeneration() <= generation);
+ }
}
}
diff --git a/PKHeX.Core/Game/GameVersion.cs b/PKHeX.Core/Game/GameVersion.cs
index 3fe64fba8..fab7b8ddd 100644
--- a/PKHeX.Core/Game/GameVersion.cs
+++ b/PKHeX.Core/Game/GameVersion.cs
@@ -40,88 +40,4 @@
EventsGBGen2,
VCEvents
}
-
- public static partial class Extensions
- {
- public static int GetGeneration(this GameVersion g)
- {
- if (GameVersion.Gen1.Contains(g)) return 1;
- if (GameVersion.Gen2.Contains(g)) return 2;
- if (GameVersion.Gen3.Contains(g)) return 3;
- if (GameVersion.Gen4.Contains(g)) return 4;
- if (GameVersion.Gen5.Contains(g)) return 5;
- if (GameVersion.Gen6.Contains(g)) return 6;
- if (GameVersion.Gen7.Contains(g)) return 7;
- return -1;
- }
- public static bool Contains(this GameVersion g1, GameVersion g2)
- {
- if (g1 == g2 || g1 == GameVersion.Any)
- return true;
-
- switch (g1)
- {
- case GameVersion.RB:
- return g2 == GameVersion.RD || g2 == GameVersion.BU || g2 == GameVersion.GN;
- case GameVersion.RBY:
- return GameVersion.RB.Contains(g2) || g2 == GameVersion.YW;
- case GameVersion.Gen1:
- return GameVersion.RBY.Contains(g2) || g2 == GameVersion.Stadium || g2 == GameVersion.EventsGBGen1 || g2 == GameVersion.VCEvents;
- case GameVersion.Stadium:
- case GameVersion.EventsGBGen1:
- case GameVersion.VCEvents:
- goto case GameVersion.RBY;
-
- case GameVersion.GS: return g2 == GameVersion.GD || g2 == GameVersion.SV;
- case GameVersion.GSC:
- return GameVersion.GS.Contains(g2) || g2 == GameVersion.C;
- case GameVersion.Gen2:
- return GameVersion.GSC.Contains(g2) || g2 == GameVersion.Stadium2 || g2 == GameVersion.EventsGBGen2;
- case GameVersion.Stadium2:
- case GameVersion.EventsGBGen2:
- goto case GameVersion.GSC;
- case GameVersion.GBCartEraOnly:
- return g2 == GameVersion.Stadium || g2 == GameVersion.Stadium2 || g2 == GameVersion.EventsGBGen1 || g2 == GameVersion.EventsGBGen2;
-
- case GameVersion.RS: return g2 == GameVersion.R || g2 == GameVersion.S;
- case GameVersion.RSE:
- return GameVersion.RS.Contains(g2) || g2 == GameVersion.E;
- case GameVersion.FRLG: return g2 == GameVersion.FR || g2 == GameVersion.LG;
- case GameVersion.COLO:
- case GameVersion.XD: return g2 == GameVersion.CXD;
- case GameVersion.CXD: return g2 == GameVersion.COLO || g2 == GameVersion.XD;
- case GameVersion.RSBOX: return GameVersion.RS.Contains(g2) || g2 == GameVersion.E || GameVersion.FRLG.Contains(g2);
- case GameVersion.Gen3:
- return GameVersion.RSE.Contains(g2) || GameVersion.FRLG.Contains(g2) || GameVersion.CXD.Contains(g2) || g2 == GameVersion.RSBOX;
-
- case GameVersion.DP: return g2 == GameVersion.D || g2 == GameVersion.P;
- case GameVersion.HGSS: return g2 == GameVersion.HG || g2 == GameVersion.SS;
- case GameVersion.DPPt:
- return GameVersion.DP.Contains(g2) || g2 == GameVersion.Pt;
- case GameVersion.BATREV: return GameVersion.DP.Contains(g2) || g2 == GameVersion.Pt || GameVersion.HGSS.Contains(g2);
- case GameVersion.Gen4:
- return GameVersion.DPPt.Contains(g2) || GameVersion.HGSS.Contains(g2) || g2 == GameVersion.BATREV;
-
- case GameVersion.BW: return g2 == GameVersion.B || g2 == GameVersion.W;
- case GameVersion.B2W2: return g2 == GameVersion.B2 || g2 == GameVersion.W2;
- case GameVersion.Gen5:
- return GameVersion.BW.Contains(g2) || GameVersion.B2W2.Contains(g2);
-
- case GameVersion.XY: return g2 == GameVersion.X || g2 == GameVersion.Y;
- case GameVersion.ORAS: return g2 == GameVersion.OR || g2 == GameVersion.AS;
- case GameVersion.Gen6:
- return GameVersion.XY.Contains(g2) || GameVersion.ORAS.Contains(g2);
-
- case GameVersion.SM:
- return g2 == GameVersion.SN || g2 == GameVersion.MN;
- case GameVersion.USUM:
- return g2 == GameVersion.US || g2 == GameVersion.UM;
- case GameVersion.Gen7:
- return GameVersion.SM.Contains(g2) || GameVersion.USUM.Contains(g2);
-
- default: return false;
- }
- }
- public static bool IsValid(this GameVersion g) => 0 < g && g <= GameVersion.RB;
- }
}
diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs
index 94c9a1e62..93ac4c0d3 100644
--- a/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs
+++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs
@@ -10,8 +10,6 @@ namespace PKHeX.Core
///
public static class EncounterMovesetGenerator
{
- private static readonly GameVersion[] Versions = GameUtil.GameVersions;
-
///
/// Gets possible objects that allow all moves requested to be learned.
///
@@ -24,7 +22,7 @@ namespace PKHeX.Core
{
pk.TID = info.TID;
var m = moves ?? pk.Moves;
- var vers = versions?.Length >= 1 ? versions : Versions.Where(z => z <= (GameVersion) pk.MaxGameID);
+ var vers = versions?.Length >= 1 ? versions : GameUtil.GetVersionsWithinRange(pk, pk.Format);
foreach (var ver in vers)
{
var encs = GenerateVersionEncounters(pk, m, ver);
@@ -77,7 +75,7 @@ namespace PKHeX.Core
public static IEnumerable GenerateEncounters(PKM pk, int[] moves = null, params GameVersion[] versions)
{
var m = moves ?? pk.Moves;
- var vers = versions?.Length >= 1 ? versions : Versions.Where(z => z <= (GameVersion)pk.MaxGameID);
+ var vers = versions?.Length >= 1 ? versions : GameUtil.GetVersionsWithinRange(pk, pk.Format);
return vers.SelectMany(ver => GenerateVersionEncounters(pk, m, ver));
}
@@ -89,8 +87,7 @@ namespace PKHeX.Core
/// A consumable list of possible encounters.
public static IEnumerable GenerateEncounters(PKM pk, int[] moves = null)
{
- var vers = Versions.Where(z => z <= (GameVersion)pk.MaxGameID).ToArray();
- return GenerateEncounters(pk, moves ?? pk.Moves, vers);
+ return GenerateEncounters(pk, moves ?? pk.Moves, null);
}
///
diff --git a/PKHeX.Core/Legality/Tables3.cs b/PKHeX.Core/Legality/Tables3.cs
index 9b32482df..e7b42cf43 100644
--- a/PKHeX.Core/Legality/Tables3.cs
+++ b/PKHeX.Core/Legality/Tables3.cs
@@ -13,7 +13,7 @@ namespace PKHeX.Core
internal const int MaxItemID_3_XD = 593;
internal const int MaxAbilityID_3 = 77;
internal const int MaxBallID_3 = 0xC;
- internal const int MaxGameID_3 = 5; // LG
+ internal const int MaxGameID_3 = 15; // CXD
///
/// Generation 3 -> Generation 4 Transfer Location (Pal Park)
///
diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs
index 0f463f40b..8cc2cf097 100644
--- a/PKHeX.Core/PKM/PKM.cs
+++ b/PKHeX.Core/PKM/PKM.cs
@@ -6,7 +6,7 @@ namespace PKHeX.Core
///
/// Object representing a 's data and derived properties.
///
- public abstract class PKM : ITrainerID
+ public abstract class PKM : ITrainerID, IGameValueLimit
{
public static readonly string[] Extensions = PKX.GetPKMExtensions();
public abstract int SIZE_PARTY { get; }
@@ -266,6 +266,7 @@ namespace PKHeX.Core
public abstract int MaxAbilityID { get; }
public abstract int MaxBallID { get; }
public abstract int MaxGameID { get; }
+ public virtual int MinGameID => 0;
public abstract int MaxIV { get; }
public abstract int MaxEV { get; }
public abstract int OTLength { get; }
diff --git a/PKHeX.Core/PKM/Shared/IGameValueLimit.cs b/PKHeX.Core/PKM/Shared/IGameValueLimit.cs
new file mode 100644
index 000000000..09576d625
--- /dev/null
+++ b/PKHeX.Core/PKM/Shared/IGameValueLimit.cs
@@ -0,0 +1,17 @@
+namespace PKHeX.Core
+{
+ public interface IGameValueLimit
+ {
+ int MaxMoveID { get; }
+ int MaxSpeciesID { get; }
+ int MaxItemID { get; }
+ int MaxAbilityID { get; }
+ int MaxBallID { get; }
+ int MaxGameID { get; }
+ int MinGameID { get; }
+ int MaxIV { get; }
+ int MaxEV { get; }
+ int OTLength { get; }
+ int NickLength { get; }
+ }
+}
diff --git a/PKHeX.Core/PKM/Util/PKMSorting.cs b/PKHeX.Core/PKM/Util/PKMSorting.cs
index 14ae0de97..d475086b1 100644
--- a/PKHeX.Core/PKM/Util/PKMSorting.cs
+++ b/PKHeX.Core/PKM/Util/PKMSorting.cs
@@ -108,7 +108,7 @@ namespace PKHeX.Core
public static IEnumerable OrderByOwnership(this IEnumerable list, ITrainerInfo trainer)
{
return list.InitialSortBy()
- .ThenByDescending(p => trainer.IsOriginalHandler(p, ((GameVersion)trainer.Game).IsValid())) // true first
+ .ThenByDescending(p => trainer.IsOriginalHandler(p, ((GameVersion)trainer.Game).IsValidSavedVersion())) // true first
.ThenByDescending(p => string.Equals(p.OT_Name, trainer.OT, StringComparison.CurrentCultureIgnoreCase))
.OrderByTrainer()
.ThenBy(p => p.Species)
diff --git a/PKHeX.Core/PKM/Util/StringConverter.cs b/PKHeX.Core/PKM/Util/StringConverter.cs
index 6435e2818..88a47a361 100644
--- a/PKHeX.Core/PKM/Util/StringConverter.cs
+++ b/PKHeX.Core/PKM/Util/StringConverter.cs
@@ -125,7 +125,7 @@ namespace PKHeX.Core
public static string GetG1ConvertedString(byte[] strdata, bool jp)
{
var table = jp ? jp_table : us_table;
- return Util.TrimFromZero(new string(strdata.TakeWhile(b => b != 0).Select(b => (char)table[b]).ToArray()));
+ return string.Concat(strdata.TakeWhile(b => b != 0).Select(b => (char)table[b]).TakeWhile(b => b != 0));
}
///
diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs
index 0c6009984..09620c6c6 100644
--- a/PKHeX.Core/Saves/SaveFile.cs
+++ b/PKHeX.Core/Saves/SaveFile.cs
@@ -8,7 +8,7 @@ namespace PKHeX.Core
///
/// Base Class for Save Files
///
- public abstract class SaveFile : ITrainerInfo
+ public abstract class SaveFile : ITrainerInfo, IGameValueLimit
{
public static bool SetUpdateDex { protected get; set; } = true;
public static bool SetUpdatePKM { protected get; set; } = true;
@@ -91,6 +91,7 @@ namespace PKHeX.Core
public abstract int MaxItemID { get; }
public abstract int MaxBallID { get; }
public abstract int MaxGameID { get; }
+ public virtual int MinGameID => 0;
// Flags
public bool HasWondercards => WondercardData > -1;
diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
index 25caff668..3a5fa1ec5 100644
--- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
+++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs
@@ -1675,7 +1675,8 @@ namespace PKHeX.WinForms.Controls
CB_Ball.DataSource = new BindingSource(GameInfo.BallDataSource.Where(b => b.Value <= SAV.MaxBallID).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.SpeciesDataSource.Where(s => s.Value <= SAV.MaxSpeciesID).ToList(), null);
DEV_Ability.DataSource = new BindingSource(GameInfo.AbilityDataSource.Where(a => a.Value <= SAV.MaxAbilityID).ToList(), null);
- CB_GameOrigin.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(g => g.Value <= SAV.MaxGameID || SAV.Generation >= 3 && g.Value == 15).ToList(), null);
+ var gamelist = GameUtil.GetVersionsWithinRange(SAV, SAV.Generation).ToList();
+ CB_GameOrigin.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(g => gamelist.Contains((GameVersion)g.Value)).ToList(), null);
// Set the Move ComboBoxes too..
GameInfo.Strings.MoveDataSource = (HaX ? GameInfo.HaXMoveDataSource : GameInfo.LegalMoveDataSource).Where(m => m.Value <= SAV.MaxMoveID).ToList(); // Filter Z-Moves if appropriate