Extract datasource filtered lists to object

GameInfo has been the storage for the current Game Language environment
When using GameInfo, only one environment is tracked at a time, which is
initialized by the PKM editor (items, moves). Rework things to allow
multiple filtered sources to exist, and keep the filtering logic in
PKHeX.Core for reuse in other programs... ;)
This commit is contained in:
Kurt
2019-06-22 10:50:32 -07:00
parent 32df9f2c39
commit cbd039b18c
17 changed files with 642 additions and 536 deletions

View File

@@ -22,12 +22,6 @@ public static List<string> GetSuggestionMessage(PKM pkm, int level, int location
return suggestion;
}
public static IReadOnlyList<ComboItem> GetAbilityList(PKM pkm)
{
var abils = pkm.PersonalInfo.Abilities;
return GameInfo.GetAbilityList(abils, pkm.Format);
}
/// <summary>
/// Applies junk data to a <see cref="SaveFile.BlankPKM"/>, which is preferable to a completely empty entity.
/// </summary>

View File

@@ -245,7 +245,7 @@ private bool ParseEntry(string identifier, string value)
/// Gets the localized Text representation of the set details.
/// </summary>
/// <param name="lang">2 character language code</param>
public string LocalizedText(string lang) => LocalizedText(GameInfo.Language(lang));
public string LocalizedText(string lang) => LocalizedText(GameLanguage.GetLanguageIndex(lang));
/// <summary>
/// Gets the localized Text representation of the set details.

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
/// <summary>
/// <see cref="SaveFile"/> sensitive provider for <see cref="ComboItem"/> data sources.
/// </summary>
public class FilteredGameDataSource
{
public FilteredGameDataSource(SaveFile sav, GameDataSource source, bool HaX = false)
{
Source = source;
if (sav.Generation > 1)
{
var items = Source.GetItemDataSource(sav.Version, sav.Generation, sav.MaxItemID, sav.HeldItems, HaX);
Items = items.Where(i => i.Value <= sav.MaxItemID).ToList();
}
else
{
Items = Array.Empty<ComboItem>();
}
var gamelist = GameUtil.GetVersionsWithinRange(sav, sav.Generation).ToList();
Games = Source.VersionDataSource.Where(g => gamelist.Contains((GameVersion)g.Value)).ToList();
Languages = GameDataSource.LanguageDataSource(sav.Generation);
Balls = Source.BallDataSource.Where(b => b.Value <= sav.MaxBallID).ToList();
Species = Source.SpeciesDataSource.Where(s => s.Value <= sav.MaxSpeciesID).ToList();
Abilities = Source.AbilityDataSource.Where(a => a.Value <= sav.MaxAbilityID).ToList();
var moves = HaX ? Source.HaXMoveDataSource : Source.LegalMoveDataSource; // Filter Z-Moves if appropriate
Moves = moves.Where(m => m.Value <= sav.MaxMoveID).ToList();
G4EncounterTypes = Source.EncounterTypeDataSource;
Natures = Source.NatureDataSource;
}
public readonly GameDataSource Source;
public readonly IReadOnlyList<ComboItem> Moves;
public readonly IReadOnlyList<ComboItem> Balls;
public readonly IReadOnlyList<ComboItem> Games;
public readonly IReadOnlyList<ComboItem> Items;
public readonly IReadOnlyList<ComboItem> Species;
public readonly IReadOnlyList<ComboItem> Languages;
public readonly IReadOnlyList<ComboItem> Abilities;
public readonly IReadOnlyList<ComboItem> Natures;
public readonly IReadOnlyList<ComboItem> G4EncounterTypes;
public readonly IReadOnlyList<ComboItem> ConsoleRegions = GameDataSource.Regions;
public IReadOnlyList<ComboItem> GetAbilityList(PKM pkm)
{
var abils = pkm.PersonalInfo.Abilities;
int format = pkm.Format;
return GetAbilityList(abils, format);
}
public IReadOnlyList<ComboItem> GetAbilityList(int[] abils, int format)
{
var count = format == 3 && (abils[1] == 0 || abils[1] == abils[0]) ? 1 : abils.Length;
var list = new ComboItem[count];
for (int i = 0; i < list.Length; i++)
{
var ability = abils[i];
list[i] = new ComboItem(Source.Source.Ability[ability] + abilIdentifier[i], ability);
}
return list;
}
private static readonly string[] abilIdentifier = { " (1)", " (2)", " (H)" };
}
}

View File

@@ -0,0 +1,284 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
/// <summary>
/// Bundles raw string inputs into lists that can be used in data binding.
/// </summary>
public class GameDataSource
{
public static readonly IReadOnlyList<ComboItem> Regions = Util.GetCSVUnsortedCBList("regions3ds");
public static readonly IReadOnlyList<ComboItem> LanguageList = Util.GetCSVUnsortedCBList("languages");
public static readonly string[] Languages = LanguageList.GetArray();
// ignores Poke/Great/Ultra
private static readonly int[] ball_nums = { 007, 576, 013, 492, 497, 014, 495, 493, 496, 494, 011, 498, 008, 006, 012, 015, 009, 005, 499, 010, 001, 016, 851 };
private static readonly int[] ball_vals = { 007, 025, 013, 017, 022, 014, 020, 018, 021, 019, 011, 023, 008, 006, 012, 015, 009, 005, 024, 010, 001, 016, 026 };
public GameDataSource(GameStrings s)
{
Source = s;
BallDataSource = Util.GetVariedCBListBall(s.itemlist, ball_nums, ball_vals);
SpeciesDataSource = Util.GetCBList(s.specieslist);
NatureDataSource = Util.GetCBList(s.natures);
AbilityDataSource = Util.GetCBList(s.abilitylist);
EncounterTypeDataSource = Util.GetCBList(s.encountertypelist, new[] { 0 }, Legal.Gen4EncounterTypes);
HaXMoveDataSource = Util.GetCBList(s.movelist);
LegalMoveDataSource = HaXMoveDataSource.Where(m => !Legal.Z_Moves.Contains(m.Value)).ToList();
VersionDataSource = GetVersionList(s);
InitializeMetSources();
Memories = new MemoryStrings(s);
}
public readonly GameStrings Source;
public readonly MemoryStrings Memories;
public readonly IReadOnlyList<ComboItem> SpeciesDataSource;
public readonly IReadOnlyList<ComboItem> BallDataSource;
public readonly IReadOnlyList<ComboItem> NatureDataSource;
public readonly IReadOnlyList<ComboItem> AbilityDataSource;
public readonly IReadOnlyList<ComboItem> VersionDataSource;
public readonly IReadOnlyList<ComboItem> LegalMoveDataSource;
public readonly IReadOnlyList<ComboItem> HaXMoveDataSource;
public readonly IReadOnlyList<ComboItem> EncounterTypeDataSource;
private IReadOnlyList<ComboItem> MetGen2 { get; set; }
private IReadOnlyList<ComboItem> MetGen3 { get; set; }
private IReadOnlyList<ComboItem> MetGen3CXD { get; set; }
private IReadOnlyList<ComboItem> MetGen4 { get; set; }
private IReadOnlyList<ComboItem> MetGen5 { get; set; }
private IReadOnlyList<ComboItem> MetGen6 { get; set; }
private IReadOnlyList<ComboItem> MetGen7 { get; set; }
private IReadOnlyList<ComboItem> MetGen7GG { get; set; }
private IReadOnlyList<ComboItem> GetVersionList(GameStrings s)
{
var list = s.gamelist;
var ver = Util.GetCBList(list,
Legal.Games_7gg,
Legal.Games_7usum, Legal.Games_7sm,
Legal.Games_6oras, Legal.Games_6xy,
Legal.Games_5, Legal.Games_4, Legal.Games_4e, Legal.Games_4r,
Legal.Games_3, Legal.Games_3e, Legal.Games_3r, Legal.Games_3s);
ver.AddRange(Util.GetCBList(list, Legal.Games_7vc1).OrderBy(g => g.Value)); // stuff to end unsorted
ver.AddRange(Util.GetCBList(list, Legal.Games_7vc2).OrderBy(g => g.Value)); // stuff to end unsorted
ver.AddRange(Util.GetCBList(list, Legal.Games_7go).OrderBy(g => g.Value)); // stuff to end unsorted
return ver;
}
private void InitializeMetSources()
{
var s = Source;
// Gen 2
{
var met_list = Util.GetCBList(s.metGSC_00000, Enumerable.Range(0, 0x5F).ToArray());
Util.AddCBWithOffset(met_list, s.metGSC_00000, 00000, 0x7E, 0x7F);
MetGen2 = met_list;
}
// Gen 3
{
var met_list = Util.GetCBList(s.metRSEFRLG_00000, Enumerable.Range(0, 213).ToArray());
Util.AddCBWithOffset(met_list, s.metRSEFRLG_00000, 00000, 253, 254, 255);
MetGen3 = met_list;
MetGen3CXD = Util.GetCBList(s.metCXD_00000, Enumerable.Range(0, s.metCXD_00000.Length).ToArray()).Where(c => c.Text.Length > 0).ToList();
}
// Gen 4
{
var met_list = Util.GetCBList(s.metHGSS_00000, 0);
Util.AddCBWithOffset(met_list, s.metHGSS_02000, 2000, Locations.Daycare4);
Util.AddCBWithOffset(met_list, s.metHGSS_02000, 2000, Locations.LinkTrade4);
Util.AddCBWithOffset(met_list, s.metHGSS_03000, 3000, Locations.Ranger4);
Util.AddCBWithOffset(met_list, s.metHGSS_00000, 0000, Legal.Met_HGSS_0);
Util.AddCBWithOffset(met_list, s.metHGSS_02000, 2000, Legal.Met_HGSS_2);
Util.AddCBWithOffset(met_list, s.metHGSS_03000, 3000, Legal.Met_HGSS_3);
MetGen4 = met_list;
}
// Gen 5
{
var met_list = Util.GetCBList(s.metBW2_00000, 0);
Util.AddCBWithOffset(met_list, s.metBW2_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, s.metBW2_30000, 30001, Locations.LinkTrade5);
Util.AddCBWithOffset(met_list, s.metBW2_00000, 00000, Legal.Met_BW2_0);
Util.AddCBWithOffset(met_list, s.metBW2_30000, 30001, Legal.Met_BW2_3);
Util.AddCBWithOffset(met_list, s.metBW2_40000, 40001, Legal.Met_BW2_4);
Util.AddCBWithOffset(met_list, s.metBW2_60000, 60001, Legal.Met_BW2_6);
MetGen5 = met_list;
}
// Gen 6
{
var met_list = Util.GetCBList(s.metXY_00000, 0);
Util.AddCBWithOffset(met_list, s.metXY_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, s.metXY_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, s.metXY_00000, 00000, Legal.Met_XY_0);
Util.AddCBWithOffset(met_list, s.metXY_30000, 30001, Legal.Met_XY_3);
Util.AddCBWithOffset(met_list, s.metXY_40000, 40001, Legal.Met_XY_4);
Util.AddCBWithOffset(met_list, s.metXY_60000, 60001, Legal.Met_XY_6);
MetGen6 = met_list;
}
// Gen 7
{
var met_list = Util.GetCBList(s.metSM_00000, 0);
Util.AddCBWithOffset(met_list, s.metSM_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, s.metSM_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, s.metSM_00000, 00000, Legal.Met_SM_0);
Util.AddCBWithOffset(met_list, s.metSM_30000, 30001, Legal.Met_SM_3);
Util.AddCBWithOffset(met_list, s.metSM_40000, 40001, Legal.Met_SM_4);
Util.AddCBWithOffset(met_list, s.metSM_60000, 60001, Legal.Met_SM_6);
MetGen7 = met_list;
}
// Gen 7 GG
{
var met_list = Util.GetCBList(s.metGG_00000, 0);
Util.AddCBWithOffset(met_list, s.metGG_60000, 60001, 60002);
Util.AddCBWithOffset(met_list, s.metGG_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, s.metGG_00000, 00000, Legal.Met_GG_0);
Util.AddCBWithOffset(met_list, s.metGG_30000, 30001, Legal.Met_GG_3);
Util.AddCBWithOffset(met_list, s.metGG_40000, 40001, Legal.Met_GG_4);
Util.AddCBWithOffset(met_list, s.metGG_60000, 60001, Legal.Met_GG_6);
MetGen7GG = met_list;
}
}
public IReadOnlyList<ComboItem> GetItemDataSource(GameVersion game, int generation, int MaxItemID, IEnumerable<ushort> allowed = null, bool HaX = false)
{
var items = Source.GetItemStrings(generation, game);
return Util.GetCBList(items, (allowed == null || HaX ? Enumerable.Range(0, MaxItemID) : allowed.Select(i => (int)i)).ToArray());
}
/// <summary>
/// Fetches a Met Location list for a <see cref="version"/> that has been transferred away from and overwritten.
/// </summary>
/// <param name="version">Origin version</param>
/// <param name="currentGen">Current savefile generation</param>
/// <param name="egg">True if an egg location list, false if a regular met location list</param>
/// <returns>Met location list</returns>
public IReadOnlyList<ComboItem> GetLocationList(GameVersion version, int currentGen, bool egg = false)
{
if (currentGen == 2)
return MetGen2;
if (egg && version < GameVersion.W && currentGen >= 5)
return MetGen4;
switch (version)
{
case GameVersion.CXD:
if (currentGen == 3)
return MetGen3CXD;
break;
case GameVersion.R:
case GameVersion.S:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value <= 87).ToList(); // Ferry
break;
case GameVersion.E:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value <= 87 || (loc.Value >= 196 && loc.Value <= 212)).ToList(); // Trainer Hill
break;
case GameVersion.FR:
case GameVersion.LG:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value > 87 && loc.Value < 197).ToList(); // Celadon Dept.
break;
case GameVersion.D:
case GameVersion.P:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value <= 111)).ToList(); // Battle Park
break;
case GameVersion.Pt:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value <= 125)).ToList(); // Rock Peak Ruins
break;
case GameVersion.HG:
case GameVersion.SS:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value > 125 && loc.Value < 234)).ToList(); // Celadon Dept.
break;
case GameVersion.B:
case GameVersion.W:
return MetGen5;
case GameVersion.B2:
case GameVersion.W2:
return MetGen5.Take(3).Concat(MetGen5.Skip(3).OrderByDescending(loc => loc.Value <= 116)).ToList(); // Abyssal Ruins
case GameVersion.X:
case GameVersion.Y:
return MetGen6.Take(3).Concat(MetGen6.Skip(3).OrderByDescending(loc => loc.Value <= 168)).ToList(); // Unknown Dungeon
case GameVersion.OR:
case GameVersion.AS:
return MetGen6.Take(3).Concat(MetGen6.Skip(3).OrderByDescending(loc => loc.Value > 168 && loc.Value <= 354)).ToList(); // Secret Base
case GameVersion.SN:
case GameVersion.MN:
return MetGen7.Take(3).Concat(MetGen7.Skip(3).OrderByDescending(loc => loc.Value < 200)).ToList(); // Outer Cape
case GameVersion.US:
case GameVersion.UM:
case GameVersion.RD:
case GameVersion.BU:
case GameVersion.GN:
case GameVersion.YW:
case GameVersion.GD:
case GameVersion.SV:
case GameVersion.C:
return MetGen7.Take(3).Concat(MetGen7.Skip(3).OrderByDescending(loc => loc.Value < 234)).ToList(); // Dividing Peak Tunnel
case GameVersion.GP:
case GameVersion.GE:
case GameVersion.GO:
return MetGen7GG.Take(3).Concat(MetGen7GG.Skip(3).OrderByDescending(loc => loc.Value <= 54)).ToList(); // Pokémon League
}
return GetLocationListModified(version, currentGen);
}
/// <summary>
/// Fetches a Met Location list for a <see cref="version"/> that has been transferred away from and overwritten.
/// </summary>
/// <param name="version">Origin version</param>
/// <param name="currentGen">Current savefile generation</param>
/// <returns>Met location list</returns>
private IReadOnlyList<ComboItem> GetLocationListModified(GameVersion version, int currentGen)
{
if (version <= GameVersion.CXD && currentGen == 4)
{
return MetGen4.Where(loc => loc.Value == Locations.Transfer3) // Pal Park to front
.Concat(MetGen4.Take(4))
.Concat(MetGen4.Skip(4).Where(loc => loc.Value != Locations.Transfer3)).ToList();
}
if (version < GameVersion.X && currentGen >= 5) // PokéTransfer to front
{
return MetGen5.Where(loc => loc.Value == Locations.Transfer4)
.Concat(MetGen5.Take(3))
.Concat(MetGen5.Skip(3).Where(loc => loc.Value != Locations.Transfer4)).ToList();
}
return Array.Empty<ComboItem>();
}
public static IReadOnlyList<ComboItem> LanguageDataSource(int gen)
{
var languages = LanguageList.ToList();
if (gen == 3)
languages.RemoveAll(l => l.Value >= (int)LanguageID.Korean);
else if (gen < 7)
languages.RemoveAll(l => l.Value > (int)LanguageID.Korean);
return languages;
}
}
}

View File

@@ -1,59 +1,43 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
namespace PKHeX.Core
{
/// <summary>
/// Shared instance for fetching <see cref="GameStrings"/> data
/// </summary>
public static class GameInfo
{
private static readonly string[] ptransp = { "ポケシフター", "Poké Transfer", "Poké Fret", "Pokétrasporto", "Poképorter", "Pokétransfer", "포케시프터", "宝可传送", "寶可傳送" };
private static readonly string[] lang_val = { "ja", "en", "fr", "it", "de", "es", "ko", "zh", "zh2" };
private const string DefaultLanguage = "en";
public static string CurrentLanguage { get; set; } = DefaultLanguage;
public static int Language(string lang = null) => Array.IndexOf(lang_val, lang ?? CurrentLanguage);
public static string Language2Char(uint lang) => lang > lang_val.Length ? DefaultLanguage : lang_val[lang];
private static readonly GameStrings[] Languages = new GameStrings[lang_val.Length];
private static readonly GameStrings[] Languages = new GameStrings[GameLanguage.LanguageCount];
public static string CurrentLanguage { get; set; } = GameLanguage.DefaultLanguage;
public static readonly IReadOnlyList<string> GenderSymbolUnicode = new[] {"♂", "♀", "-"};
public static readonly IReadOnlyList<string> GenderSymbolASCII = new[] {"M", "F", "-"};
// Lazy fetch implementation
private static int DefaultLanguageIndex => Array.IndexOf(lang_val, DefaultLanguage);
public static int GetLanguageIndex(string lang)
{
int l = Array.IndexOf(lang_val, lang);
return l < 0 ? DefaultLanguageIndex : l;
}
private static GameStrings _strings = GetStrings(CurrentLanguage);
public static GameStrings GetStrings(string lang)
{
int index = GetLanguageIndex(lang);
int index = GameLanguage.GetLanguageIndex(lang);
return GetStrings(index);
}
public static GameStrings GetStrings(int index)
{
return Languages[index] ?? (Languages[index] = new GameStrings(lang_val[index]));
return Languages[index] ?? (Languages[index] = new GameStrings(GameLanguage.Language2Char(index)));
}
public static string GetTransporterName(string lang)
public static GameStrings Strings
{
int index = GetLanguageIndex(lang);
if (index >= ptransp.Length)
index = DefaultLanguageIndex;
return ptransp[index];
get => _strings;
set
{
_strings = value;
Sources = new GameDataSource(_strings);
FilteredSources = null;
}
}
public static GameStrings Strings { get; set; } = GetStrings(DefaultLanguage);
public static string[] GetStrings(string ident, string lang, string type = "text")
{
string[] data = Util.GetStringList(ident, lang, type);
if (data == null || data.Length == 0)
data = Util.GetStringList(ident, DefaultLanguage, type);
return data;
}
public static GameDataSource Sources { get; set; }
public static FilteredGameDataSource FilteredSources { get; set; }
public static string GetVersionName(GameVersion version)
{
@@ -63,111 +47,17 @@ public static string GetVersionName(GameVersion version)
}
// DataSource providing
public static IReadOnlyList<ComboItem> ItemDataSource => Strings.ItemDataSource;
public static IReadOnlyList<ComboItem> SpeciesDataSource => Strings.SpeciesDataSource;
public static IReadOnlyList<ComboItem> BallDataSource => Strings.BallDataSource;
public static IReadOnlyList<ComboItem> NatureDataSource => Strings.NatureDataSource;
public static IReadOnlyList<ComboItem> AbilityDataSource => Strings.AbilityDataSource;
public static IReadOnlyList<ComboItem> VersionDataSource => Strings.VersionDataSource;
public static IReadOnlyList<ComboItem> LegalMoveDataSource => Strings.LegalMoveDataSource;
public static IReadOnlyList<ComboItem> HaXMoveDataSource => Strings.HaXMoveDataSource;
public static IReadOnlyList<ComboItem> MoveDataSource => Strings.MoveDataSource;
public static IReadOnlyList<ComboItem> EncounterTypeDataSource => Strings.EncounterTypeDataSource;
public static IReadOnlyList<ComboItem> Regions => GameStrings.Regions;
public static IReadOnlyList<ComboItem> ItemDataSource => FilteredSources.Items;
public static IReadOnlyList<ComboItem> SpeciesDataSource => Sources.SpeciesDataSource;
public static IReadOnlyList<ComboItem> BallDataSource => Sources.BallDataSource;
public static IReadOnlyList<ComboItem> NatureDataSource => Sources.NatureDataSource;
public static IReadOnlyList<ComboItem> AbilityDataSource => Sources.AbilityDataSource;
public static IReadOnlyList<ComboItem> VersionDataSource => Sources.VersionDataSource;
public static IReadOnlyList<ComboItem> MoveDataSource => Sources.HaXMoveDataSource;
public static IReadOnlyList<ComboItem> EncounterTypeDataSource => Sources.EncounterTypeDataSource;
public static IReadOnlyList<ComboItem> Regions => GameDataSource.Regions;
public static IReadOnlyList<ComboItem> LanguageDataSource(int gen) => GameStrings.LanguageDataSource(gen);
public static IReadOnlyList<ComboItem> GetAbilityList(int[] abils, int format)
{
if (format == 3 && abils[1] == abils[0])
abils = new[] { abils[0] };
return Strings.GetAbilityDataSource(abils);
}
/// <summary>
/// Gets the location names array for a specified generation.
/// </summary>
/// <param name="gen">Generation to get location names for.</param>
/// <param name="bankID">BankID used to choose the text bank.</param>
/// <param name="version">Version of origin</param>
/// <returns>List of location names.</returns>
private static IReadOnlyList<string> GetLocationNames(int gen, int bankID, GameVersion version)
{
switch (gen)
{
case 2: return Strings.metGSC_00000;
case 3:
return version == GameVersion.CXD ? Strings.metCXD_00000 : Strings.metRSEFRLG_00000;
case 4: return GetLocationNames4(bankID);
case 5: return GetLocationNames5(bankID);
case 6: return GetLocationNames6(bankID);
case 7:
if (GameVersion.GG.Contains(version))
return GetLocationNames7GG(bankID);
return GetLocationNames7(bankID);
default:
return Array.Empty<string>();
}
}
private static IReadOnlyList<string> GetLocationNames4(int bankID)
{
switch (bankID)
{
case 0: return Strings.metHGSS_00000;
case 2: return Strings.metHGSS_02000;
case 3: return Strings.metHGSS_03000;
default: return Array.Empty<string>();
}
}
private static IReadOnlyList<string> GetLocationNames5(int bankID)
{
switch (bankID)
{
case 0: return Strings.metBW2_00000;
case 3: return Strings.metBW2_30000;
case 4: return Strings.metBW2_40000;
case 6: return Strings.metBW2_60000;
default: return Array.Empty<string>();
}
}
private static IReadOnlyList<string> GetLocationNames6(int bankID)
{
switch (bankID)
{
case 0: return Strings.metXY_00000;
case 3: return Strings.metXY_30000;
case 4: return Strings.metXY_40000;
case 6: return Strings.metXY_60000;
default: return Array.Empty<string>();
}
}
private static IReadOnlyList<string> GetLocationNames7(int bankID)
{
switch (bankID)
{
case 0: return Strings.metSM_00000;
case 3: return Strings.metSM_30000;
case 4: return Strings.metSM_40000;
case 6: return Strings.metSM_60000;
default: return Array.Empty<string>();
}
}
private static IReadOnlyList<string> GetLocationNames7GG(int bankID)
{
switch (bankID)
{
case 0: return Strings.metGG_00000;
case 3: return Strings.metGG_30000;
case 4: return Strings.metGG_40000;
case 6: return Strings.metGG_60000;
default: return Array.Empty<string>();
}
}
public static IReadOnlyList<ComboItem> LanguageDataSource(int gen) => GameDataSource.LanguageDataSource(gen);
/// <summary>
/// Gets the location name for the specified parameters.
@@ -180,44 +70,7 @@ private static IReadOnlyList<string> GetLocationNames7GG(int bankID)
/// <returns>Location name</returns>
public static string GetLocationName(bool eggmet, int locval, int format, int generation, GameVersion version)
{
int gen = -1;
int bankID = 0;
if (format == 2)
{
gen = 2;
}
else if (format == 3)
{
gen = 3;
}
else if (generation == 4 && (eggmet || format == 4)) // 4
{
const int size = 1000;
bankID = locval / size;
gen = 4;
locval %= size;
}
else // 5-7+
{
const int size = 10000;
bankID = locval / size;
int g = generation;
if (g >= 5)
gen = g;
else if (format >= 5)
gen = format;
locval %= size;
if (bankID >= 3) // 30000 and onwards don't use 0th index, shift down 1
locval--;
}
var bank = GetLocationNames(gen, bankID, version);
if (bank.Count <= locval)
return string.Empty;
return bank[locval];
return Strings.GetLocationName(eggmet, locval, format, generation, version);
}
/// <summary>
@@ -229,7 +82,7 @@ public static string GetLocationName(bool eggmet, int locval, int format, int ge
/// <returns>Consumable list of met locations</returns>
public static IReadOnlyList<ComboItem> GetLocationList(GameVersion version, int pkmFormat, bool egg = false)
{
return Strings.GetLocationList(version, pkmFormat, egg);
return Sources.GetLocationList(version, pkmFormat, egg);
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
namespace PKHeX.Core
{
/// <summary>
/// Language code &amp; string asset loading.
/// </summary>
public static class GameLanguage
{
public const string DefaultLanguage = "en"; // English
public static int DefaultLanguageIndex => Array.IndexOf(LanguageCodes, DefaultLanguage);
public static string Language2Char(int lang) => lang > LanguageCodes.Length ? DefaultLanguage : LanguageCodes[lang];
public static int LanguageCount => LanguageCodes.Length;
public static int GetLanguageIndex(string lang)
{
int l = Array.IndexOf(LanguageCodes, lang);
return l < 0 ? DefaultLanguageIndex : l;
}
/// <summary>
/// Language codes supported for loading string resources
/// </summary>
/// <see cref="ProgramLanguage"/>
private static readonly string[] LanguageCodes = { "ja", "en", "fr", "it", "de", "es", "ko", "zh", "zh2" };
/// <summary>
/// Pokétransporter location names, ordered per index of <see cref="LanguageCodes"/>
/// </summary>
private static readonly string[] ptransp = { "ポケシフター", "Poké Transfer", "Poké Fret", "Pokétrasporto", "Poképorter", "Pokétransfer", "포케시프터", "宝可传送", "寶可傳送" };
public static string GetTransporterName(int index)
{
if ((uint)index >= ptransp.Length)
index = 2;
return ptransp[index];
}
public static string GetTransporterName(string lang) => GetTransporterName(GetLanguageIndex(lang));
public static string[] GetStrings(string ident, string lang, string type = "text")
{
string[] data = Util.GetStringList(ident, lang, type);
if (data == null || data.Length == 0)
data = Util.GetStringList(ident, DefaultLanguage, type);
return data;
}
}
public enum ProgramLanguage
{
/// <summary>
/// Japanese
/// </summary>
,
/// <summary>
/// English
/// </summary>
English,
/// <summary>
/// French
/// </summary>
Français,
/// <summary>
/// Italian
/// </summary>
Italiano,
/// <summary>
/// German
/// </summary>
Deutsch,
/// <summary>
/// Spanish
/// </summary>
Español,
/// <summary>
/// Korean
/// </summary>
,
/// <summary>
/// Chinese
/// </summary>
,
}
}

View File

@@ -9,7 +9,7 @@ public class GameStrings : IBasicStrings
// PKM Info
public readonly string[] specieslist, movelist, itemlist, abilitylist, types, natures, forms,
memories, genloc, trainingbags, trainingstage, characteristics,
encountertypelist, gamelanguages, balllist, gamelist, pokeblocks, ribbons;
encountertypelist, balllist, gamelist, pokeblocks, ribbons;
private readonly string[] g4items, g3coloitems, g3xditems, g3items, g2items, g1items;
@@ -24,6 +24,7 @@ public class GameStrings : IBasicStrings
// Misc
public readonly string[] wallpapernames, puffs;
private readonly string lang;
private readonly int LanguageIndex;
public string EggName { get; }
public IReadOnlyList<string> Species => specieslist;
@@ -33,16 +34,14 @@ public class GameStrings : IBasicStrings
public IReadOnlyList<string> Types => types;
public IReadOnlyList<string> Natures => natures;
private string[] Get(string ident) => GameInfo.GetStrings(ident, lang);
private string[] Get(string ident) => GameLanguage.GetStrings(ident, lang);
private const string NPC = "NPC";
private static readonly string[] abilIdentifier = { " (1)", " (2)", " (H)" };
public static readonly IReadOnlyList<ComboItem> Regions = Util.GetCSVUnsortedCBList("regions3ds");
private static readonly IReadOnlyList<ComboItem> LanguageList = Util.GetCSVUnsortedCBList("languages");
private static readonly string[] LanguageNames = LanguageList.GetArray();
private static readonly string[] LanguageNames = GameDataSource.LanguageList.GetArray();
public GameStrings(string l)
{
lang = l;
LanguageIndex = GameLanguage.GetLanguageIndex(l);
ribbons = Get("ribbons");
// Past Generation strings
g3items = Get("ItemsG3");
@@ -86,7 +85,6 @@ public GameStrings(string l)
wallpapernames = Get("wallpaper");
encountertypelist = Get("encountertype");
gamelist = Get("games");
gamelanguages = LanguageNames;
balllist = new string[Legal.Items_Ball.Length];
for (int i = 0; i < balllist.Length; i++)
@@ -128,8 +126,6 @@ public GameStrings(string l)
g4items = (string[])itemlist.Clone();
Get("mail4").CopyTo(g4items, 137);
InitializeDataSources();
}
private static string[] SanitizeMetStringsCXD(string[] cxd)
@@ -231,7 +227,7 @@ private void SanitizeMetG5BW()
metBW2_00000[2] += " (2)";
// Localize the Poketransfer to the language (30001)
metBW2_30000[1 - 1] = GameInfo.GetTransporterName(lang); // Default to English
metBW2_30000[1 - 1] = GameLanguage.GetTransporterName(LanguageIndex);
metBW2_30000[2 - 1] += $" ({NPC})"; // Anything from an NPC
metBW2_30000[3 - 1] += $" ({EggName})"; // Link Trade (Egg)
@@ -306,277 +302,140 @@ private string[] GetItemStrings3(GameVersion game)
}
}
// DataSource providing
public IReadOnlyList<ComboItem> ItemDataSource { get; private set; }
public IReadOnlyList<ComboItem> SpeciesDataSource { get; private set; }
public IReadOnlyList<ComboItem> BallDataSource { get; private set; }
public IReadOnlyList<ComboItem> NatureDataSource { get; private set; }
public IReadOnlyList<ComboItem> AbilityDataSource { get; private set; }
public IReadOnlyList<ComboItem> VersionDataSource { get; private set; }
public IReadOnlyList<ComboItem> LegalMoveDataSource { get; private set; }
public IReadOnlyList<ComboItem> HaXMoveDataSource { get; private set; }
public IReadOnlyList<ComboItem> MoveDataSource { get; set; }
public IReadOnlyList<ComboItem> EncounterTypeDataSource { get; private set; }
private IReadOnlyList<ComboItem> MetGen2 { get; set; }
private IReadOnlyList<ComboItem> MetGen3 { get; set; }
private IReadOnlyList<ComboItem> MetGen3CXD { get; set; }
private IReadOnlyList<ComboItem> MetGen4 { get; set; }
private IReadOnlyList<ComboItem> MetGen5 { get; set; }
private IReadOnlyList<ComboItem> MetGen6 { get; set; }
private IReadOnlyList<ComboItem> MetGen7 { get; set; }
private IReadOnlyList<ComboItem> MetGen7GG { get; set; }
public MemoryStrings Memories { get; private set; }
// ignores Poke/Great/Ultra
private static readonly int[] ball_nums = { 007, 576, 013, 492, 497, 014, 495, 493, 496, 494, 011, 498, 008, 006, 012, 015, 009, 005, 499, 010, 001, 016, 851 };
private static readonly int[] ball_vals = { 007, 025, 013, 017, 022, 014, 020, 018, 021, 019, 011, 023, 008, 006, 012, 015, 009, 005, 024, 010, 001, 016, 026 };
private void InitializeDataSources()
/// <summary>
/// Gets the location name for the specified parameters.
/// </summary>
/// <param name="eggmet">Location is from the <see cref="PKM.Egg_Location"/></param>
/// <param name="locval">Location value</param>
/// <param name="format">Current <see cref="PKM.Format"/></param>
/// <param name="generation"><see cref="PKM.GenNumber"/> of origin</param>
/// <param name="version">Current GameVersion (only applicable for <see cref="GameVersion.GG"/> differentiation)</param>
/// <returns>Location name</returns>
public string GetLocationName(bool eggmet, int locval, int format, int generation, GameVersion version)
{
BallDataSource = Util.GetVariedCBListBall(itemlist, ball_nums, ball_vals);
SpeciesDataSource = Util.GetCBList(specieslist);
NatureDataSource = Util.GetCBList(natures);
AbilityDataSource = Util.GetCBList(abilitylist);
VersionDataSource = GetVersionList();
EncounterTypeDataSource = Util.GetCBList(encountertypelist, new[] {0}, Legal.Gen4EncounterTypes);
int gen = -1;
int bankID = 0;
HaXMoveDataSource = Util.GetCBList(movelist);
MoveDataSource = LegalMoveDataSource = HaXMoveDataSource.Where(m => !Legal.Z_Moves.Contains(m.Value)).ToList();
InitializeMetSources();
Memories = new MemoryStrings(this);
}
if (format == 2)
{
gen = 2;
}
else if (format == 3)
{
gen = 3;
}
else if (generation == 4 && (eggmet || format == 4)) // 4
{
const int size = 1000;
bankID = locval / size;
gen = 4;
locval %= size;
}
else // 5-7+
{
const int size = 10000;
bankID = locval / size;
private IReadOnlyList<ComboItem> GetVersionList()
{
var ver = Util.GetCBList(gamelist,
Legal.Games_7gg,
Legal.Games_7usum, Legal.Games_7sm,
Legal.Games_6oras, Legal.Games_6xy,
Legal.Games_5, Legal.Games_4, Legal.Games_4e, Legal.Games_4r,
Legal.Games_3, Legal.Games_3e, Legal.Games_3r, Legal.Games_3s);
ver.AddRange(Util.GetCBList(gamelist, Legal.Games_7vc1).OrderBy(g => g.Value)); // stuff to end unsorted
ver.AddRange(Util.GetCBList(gamelist, Legal.Games_7vc2).OrderBy(g => g.Value)); // stuff to end unsorted
ver.AddRange(Util.GetCBList(gamelist, Legal.Games_7go).OrderBy(g => g.Value)); // stuff to end unsorted
return ver;
}
int g = generation;
if (g >= 5)
gen = g;
else if (format >= 5)
gen = format;
private void InitializeMetSources()
{
// Gen 2
{
var met_list = Util.GetCBList(metGSC_00000, Enumerable.Range(0, 0x5F).ToArray());
Util.AddCBWithOffset(met_list, metGSC_00000, 00000, 0x7E, 0x7F);
MetGen2 = met_list;
locval %= size;
if (bankID >= 3) // 30000 and onwards don't use 0th index, shift down 1
locval--;
}
// Gen 3
{
var met_list = Util.GetCBList(metRSEFRLG_00000, Enumerable.Range(0, 213).ToArray());
Util.AddCBWithOffset(met_list, metRSEFRLG_00000, 00000, 253, 254, 255);
MetGen3 = met_list;
MetGen3CXD = Util.GetCBList(metCXD_00000, Enumerable.Range(0, metCXD_00000.Length).ToArray()).Where(c => c.Text.Length > 0).ToList();
}
// Gen 4
{
var met_list = Util.GetCBList(metHGSS_00000, 0);
Util.AddCBWithOffset(met_list, metHGSS_02000, 2000, Locations.Daycare4);
Util.AddCBWithOffset(met_list, metHGSS_02000, 2000, Locations.LinkTrade4);
Util.AddCBWithOffset(met_list, metHGSS_03000, 3000, Locations.Ranger4);
Util.AddCBWithOffset(met_list, metHGSS_00000, 0000, Legal.Met_HGSS_0);
Util.AddCBWithOffset(met_list, metHGSS_02000, 2000, Legal.Met_HGSS_2);
Util.AddCBWithOffset(met_list, metHGSS_03000, 3000, Legal.Met_HGSS_3);
MetGen4 = met_list;
}
// Gen 5
{
var met_list = Util.GetCBList(metBW2_00000, 0);
Util.AddCBWithOffset(met_list, metBW2_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, metBW2_30000, 30001, Locations.LinkTrade5);
Util.AddCBWithOffset(met_list, metBW2_00000, 00000, Legal.Met_BW2_0);
Util.AddCBWithOffset(met_list, metBW2_30000, 30001, Legal.Met_BW2_3);
Util.AddCBWithOffset(met_list, metBW2_40000, 40001, Legal.Met_BW2_4);
Util.AddCBWithOffset(met_list, metBW2_60000, 60001, Legal.Met_BW2_6);
MetGen5 = met_list;
}
// Gen 6
{
var met_list = Util.GetCBList(metXY_00000, 0);
Util.AddCBWithOffset(met_list, metXY_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, metXY_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, metXY_00000, 00000, Legal.Met_XY_0);
Util.AddCBWithOffset(met_list, metXY_30000, 30001, Legal.Met_XY_3);
Util.AddCBWithOffset(met_list, metXY_40000, 40001, Legal.Met_XY_4);
Util.AddCBWithOffset(met_list, metXY_60000, 60001, Legal.Met_XY_6);
MetGen6 = met_list;
}
// Gen 7
{
var met_list = Util.GetCBList(metSM_00000, 0);
Util.AddCBWithOffset(met_list, metSM_60000, 60001, Locations.Daycare5);
Util.AddCBWithOffset(met_list, metSM_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, metSM_00000, 00000, Legal.Met_SM_0);
Util.AddCBWithOffset(met_list, metSM_30000, 30001, Legal.Met_SM_3);
Util.AddCBWithOffset(met_list, metSM_40000, 40001, Legal.Met_SM_4);
Util.AddCBWithOffset(met_list, metSM_60000, 60001, Legal.Met_SM_6);
MetGen7 = met_list;
}
// Gen 7 GG
{
var met_list = Util.GetCBList(metGG_00000, 0);
Util.AddCBWithOffset(met_list, metGG_60000, 60001, 60002);
Util.AddCBWithOffset(met_list, metGG_30000, 30001, Locations.LinkTrade6);
Util.AddCBWithOffset(met_list, metGG_00000, 00000, Legal.Met_GG_0);
Util.AddCBWithOffset(met_list, metGG_30000, 30001, Legal.Met_GG_3);
Util.AddCBWithOffset(met_list, metGG_40000, 40001, Legal.Met_GG_4);
Util.AddCBWithOffset(met_list, metGG_60000, 60001, Legal.Met_GG_6);
MetGen7GG = met_list;
}
}
public void SetItemDataSource(GameVersion game, int generation, int MaxItemID, IEnumerable<ushort> allowed = null, bool HaX = false)
{
var items = GetItemStrings(generation, game);
ItemDataSource = Util.GetCBList(items, (allowed == null || HaX ? Enumerable.Range(0, MaxItemID) : allowed.Select(i => (int)i)).ToArray());
var bank = GetLocationNames(gen, bankID, version);
if (bank.Count <= locval)
return string.Empty;
return bank[locval];
}
/// <summary>
/// Fetches a Met Location list for a <see cref="version"/> that has been transferred away from and overwritten.
/// Gets the location names array for a specified generation.
/// </summary>
/// <param name="version">Origin version</param>
/// <param name="currentGen">Current savefile generation</param>
/// <param name="egg">True if an egg location list, false if a regular met location list</param>
/// <returns>Met location list</returns>
public IReadOnlyList<ComboItem> GetLocationList(GameVersion version, int currentGen, bool egg = false)
/// <param name="gen">Generation to get location names for.</param>
/// <param name="bankID">BankID used to choose the text bank.</param>
/// <param name="version">Version of origin</param>
/// <returns>List of location names.</returns>
public IReadOnlyList<string> GetLocationNames(int gen, int bankID, GameVersion version)
{
if (currentGen == 2)
return MetGen2;
if (egg && version < GameVersion.W && currentGen >= 5)
return MetGen4;
switch (version)
switch (gen)
{
case GameVersion.CXD:
if (currentGen == 3)
return MetGen3CXD;
break;
case GameVersion.R:
case GameVersion.S:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value <= 87).ToList(); // Ferry
break;
case GameVersion.E:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value <= 87 || (loc.Value >= 196 && loc.Value <= 212)).ToList(); // Trainer Hill
break;
case GameVersion.FR:
case GameVersion.LG:
if (currentGen == 3)
return MetGen3.OrderByDescending(loc => loc.Value > 87 && loc.Value < 197).ToList(); // Celadon Dept.
break;
case GameVersion.D:
case GameVersion.P:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value <= 111)).ToList(); // Battle Park
break;
case GameVersion.Pt:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value <= 125)).ToList(); // Rock Peak Ruins
break;
case GameVersion.HG:
case GameVersion.SS:
if (currentGen == 4 || (currentGen >= 5 && egg))
return MetGen4.Take(4).Concat(MetGen4.Skip(4).OrderByDescending(loc => loc.Value > 125 && loc.Value < 234)).ToList(); // Celadon Dept.
break;
case GameVersion.B:
case GameVersion.W:
return MetGen5;
case GameVersion.B2:
case GameVersion.W2:
return MetGen5.Take(3).Concat(MetGen5.Skip(3).OrderByDescending(loc => loc.Value <= 116)).ToList(); // Abyssal Ruins
case GameVersion.X:
case GameVersion.Y:
return MetGen6.Take(3).Concat(MetGen6.Skip(3).OrderByDescending(loc => loc.Value <= 168)).ToList(); // Unknown Dungeon
case GameVersion.OR:
case GameVersion.AS:
return MetGen6.Take(3).Concat(MetGen6.Skip(3).OrderByDescending(loc => loc.Value > 168 && loc.Value <= 354)).ToList(); // Secret Base
case GameVersion.SN:
case GameVersion.MN:
return MetGen7.Take(3).Concat(MetGen7.Skip(3).OrderByDescending(loc => loc.Value < 200)).ToList(); // Outer Cape
case GameVersion.US:
case GameVersion.UM:
case GameVersion.RD:
case GameVersion.BU:
case GameVersion.GN:
case GameVersion.YW:
case GameVersion.GD:
case GameVersion.SV:
case GameVersion.C:
return MetGen7.Take(3).Concat(MetGen7.Skip(3).OrderByDescending(loc => loc.Value < 234)).ToList(); // Dividing Peak Tunnel
case GameVersion.GP:
case GameVersion.GE:
case GameVersion.GO:
return MetGen7GG.Take(3).Concat(MetGen7GG.Skip(3).OrderByDescending(loc => loc.Value <= 54)).ToList(); // Pokémon League
case 2: return metGSC_00000;
case 3:
return version == GameVersion.CXD ? metCXD_00000 : metRSEFRLG_00000;
case 4: return GetLocationNames4(bankID);
case 5: return GetLocationNames5(bankID);
case 6: return GetLocationNames6(bankID);
case 7:
if (GameVersion.GG.Contains(version))
return GetLocationNames7GG(bankID);
return GetLocationNames7(bankID);
default:
return Array.Empty<string>();
}
return GetLocationListModified(version, currentGen);
}
/// <summary>
/// Fetches a Met Location list for a <see cref="version"/> that has been transferred away from and overwritten.
/// </summary>
/// <param name="version">Origin version</param>
/// <param name="currentGen">Current savefile generation</param>
/// <returns>Met location list</returns>
private IReadOnlyList<ComboItem> GetLocationListModified(GameVersion version, int currentGen)
private IReadOnlyList<string> GetLocationNames4(int bankID)
{
if (version <= GameVersion.CXD && currentGen == 4)
switch (bankID)
{
return MetGen4.Where(loc => loc.Value == Locations.Transfer3) // Pal Park to front
.Concat(MetGen4.Take(4))
.Concat(MetGen4.Skip(4).Where(loc => loc.Value != Locations.Transfer3)).ToList();
case 0: return metHGSS_00000;
case 2: return metHGSS_02000;
case 3: return metHGSS_03000;
default: return Array.Empty<string>();
}
if (version < GameVersion.X && currentGen >= 5) // PokéTransfer to front
{
return MetGen5.Where(loc => loc.Value == Locations.Transfer4)
.Concat(MetGen5.Take(3))
.Concat(MetGen5.Skip(3).Where(loc => loc.Value != Locations.Transfer4)).ToList();
}
return Array.Empty<ComboItem>();
}
public static IReadOnlyList<ComboItem> LanguageDataSource(int gen)
public IReadOnlyList<string> GetLocationNames5(int bankID)
{
var languages = LanguageList.ToList();
if (gen == 3)
languages.RemoveAll(l => l.Value >= (int)LanguageID.Korean);
else if (gen < 7)
languages.RemoveAll(l => l.Value > (int)LanguageID.Korean);
return languages;
switch (bankID)
{
case 0: return metBW2_00000;
case 3: return metBW2_30000;
case 4: return metBW2_40000;
case 6: return metBW2_60000;
default: return Array.Empty<string>();
}
}
public IReadOnlyList<ComboItem> GetAbilityDataSource(IEnumerable<int> abils)
public IReadOnlyList<string> GetLocationNames6(int bankID)
{
return abils.Select(GetItem).ToList();
ComboItem GetItem(int ability, int index)
=> new ComboItem(abilitylist[ability] + abilIdentifier[index], ability);
switch (bankID)
{
case 0: return metXY_00000;
case 3: return metXY_30000;
case 4: return metXY_40000;
case 6: return metXY_60000;
default: return Array.Empty<string>();
}
}
public IReadOnlyList<string> GetLocationNames7(int bankID)
{
switch (bankID)
{
case 0: return metSM_00000;
case 3: return metSM_30000;
case 4: return metSM_40000;
case 6: return metSM_60000;
default: return Array.Empty<string>();
}
}
public IReadOnlyList<string> GetLocationNames7GG(int bankID)
{
switch (bankID)
{
case 0: return metGG_00000;
case 3: return metGG_30000;
case 4: return metGG_40000;
case 6: return metGG_60000;
default: return Array.Empty<string>();
}
}
}
}

View File

@@ -224,7 +224,7 @@ public static void SetLocalization(Type t, string currentCultureCode)
#region DataSource Providing
private static readonly string[] CountryRegionLanguages = {"ja", "en", "fr", "de", "it", "es", "ko", "zh"};
private static readonly string[] CountryRegionLanguages = {"ja", "en", "fr", "de", "it", "es", "zh", "ko"};
public static List<ComboItem> GetCountryRegionList(string textfile, string lang)
{

View File

@@ -405,7 +405,7 @@ private void SetAbilityList()
bool tmp = FieldsLoaded;
FieldsLoaded = false;
CB_Ability.DataSource = EditPKMUtil.GetAbilityList(pkm);
CB_Ability.DataSource = GameInfo.FilteredSources.GetAbilityList(pkm);
CB_Ability.SelectedIndex = GetSafeIndex(CB_Ability, abil); // restore original index if available
FieldsLoaded = tmp;
}
@@ -467,11 +467,7 @@ private void UpdateGender()
private void SetCountrySubRegion(ComboBox CB, string type)
{
int index = CB.SelectedIndex;
// fix for Korean / Chinese being swapped
string cl = GameInfo.CurrentLanguage;
cl = cl == "zh" ? "ko" : cl == "ko" ? "zh" : cl;
CB.DataSource = Util.GetCountryRegionList(type, cl);
CB.DataSource = Util.GetCountryRegionList(type, GameInfo.CurrentLanguage);
if (index > 0 && index < CB.Items.Count)
CB.SelectedIndex = index;
@@ -656,7 +652,8 @@ private bool SetSuggestedMoves(bool random = false, bool silent = false)
if (!silent)
{
var movestrings = m.Select(v => v >= GameInfo.Strings.Move.Count ? MsgProgramError : GameInfo.Strings.Move[v]);
var mv = GameInfo.Strings.Move;
var movestrings = m.Select(v => (uint)v >= mv.Count ? MsgProgramError : mv[v]);
var msg = string.Join(Environment.NewLine, movestrings);
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgPKMSuggestionMoves, msg))
return false;
@@ -680,7 +677,8 @@ private bool SetSuggestedRelearnMoves(bool silent = false)
if (!silent)
{
var movestrings = m.Select(v => v >= GameInfo.Strings.Move.Count ? MsgProgramError : GameInfo.Strings.Move[v]);
var mv = GameInfo.Strings.Move;
var movestrings = m.Select(v => (uint)v >= mv.Count ? MsgProgramError : mv[v]);
var msg = string.Join(Environment.NewLine, movestrings);
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgPKMSuggestionRelearn, msg))
return false;
@@ -1710,7 +1708,7 @@ private void LoadShowdownSetDefault(ShowdownSet Set)
PopulateFields(pk);
}
public void ChangeLanguage(SaveFile sav, PKM pk)
public void ChangeLanguage(ITrainerInfo sav, PKM pk)
{
// Force an update to the met locations
origintrack = GameVersion.Invalid;
@@ -1726,14 +1724,15 @@ public void FlickerInterface()
tabMain.SelectedTab = Tab_Main; // first tab
}
private void InitializeLanguage(SaveFile sav)
private void InitializeLanguage(ITrainerInfo sav)
{
var source = GameInfo.FilteredSources;
// Set the various ComboBox DataSources up with their allowed entries
SetCountrySubRegion(CB_Country, "countries");
CB_3DSReg.DataSource = GameInfo.Regions;
CB_3DSReg.DataSource = source.ConsoleRegions;
CB_EncounterType.DataSource = new BindingSource(GameInfo.EncounterTypeDataSource, null);
CB_Nature.DataSource = new BindingSource(GameInfo.NatureDataSource, null);
CB_EncounterType.DataSource = new BindingSource(source.G4EncounterTypes, null);
CB_Nature.DataSource = new BindingSource(source.Natures, null);
// Sub editors
Stats.InitializeDataSources();
@@ -1741,27 +1740,24 @@ private void InitializeLanguage(SaveFile sav)
PopulateFilteredDataSources(sav);
}
private void PopulateFilteredDataSources(SaveFile sav)
private void PopulateFilteredDataSources(ITrainerInfo sav)
{
GameInfo.Strings.SetItemDataSource(sav.Version, sav.Generation, sav.MaxItemID, sav.HeldItems, HaX);
var source = GameInfo.FilteredSources;
if (sav.Generation > 1)
CB_HeldItem.DataSource = new BindingSource(GameInfo.ItemDataSource.Where(i => i.Value <= sav.MaxItemID).ToList(), null);
CB_HeldItem.DataSource = new BindingSource(source.Items, null);
CB_Language.DataSource = GameInfo.LanguageDataSource(sav.Generation);
CB_Language.DataSource = source.Languages;
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);
var gamelist = GameUtil.GetVersionsWithinRange(sav, sav.Generation).ToList();
CB_GameOrigin.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(g => gamelist.Contains((GameVersion)g.Value)).ToList(), null);
CB_Ball.DataSource = new BindingSource(source.Balls, null);
CB_Species.DataSource = new BindingSource(source.Species, null);
DEV_Ability.DataSource = new BindingSource(source.Abilities, null);
CB_GameOrigin.DataSource = new BindingSource(source.Games, 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
LegalMoveSource.ReloadMoves(GameInfo.Strings.MoveDataSource);
LegalMoveSource.ReloadMoves(source.Moves);
foreach (var cb in Moves.Concat(Relearn))
{
cb.DataSource = new BindingSource(GameInfo.MoveDataSource, null);
}
cb.DataSource = new BindingSource(source.Moves, null);
}
}
}

View File

@@ -291,10 +291,10 @@ private void FormInitializeSecond()
#endif
// Select Language
int lang = GameInfo.Language(settings.Language);
int lang = GameLanguage.GetLanguageIndex(settings.Language);
if (lang < 0)
lang = GameInfo.Language();
CB_MainLanguage.SelectedIndex = lang >= 0 ? lang : (int)ProgramLanguage.English;
lang = GameLanguage.DefaultLanguageIndex;
CB_MainLanguage.SelectedIndex = lang;
}
private void FormLoadPlugins()
@@ -734,6 +734,7 @@ private bool OpenSAV(SaveFile sav, string path)
Menu_Undo.Enabled = false;
Menu_Redo.Enabled = false;
GameInfo.FilteredSources = new FilteredGameDataSource(sav, GameInfo.Sources, HaX);
ResetSAVPKMEditors(sav);
C_SAV.M.Reset();
@@ -879,10 +880,7 @@ private static bool SanityCheckSAV(ref SaveFile sav)
public static void SetCountrySubRegion(ComboBox CB, string type)
{
int index = CB.SelectedIndex;
// fix for Korean / Chinese being swapped
string cl = GameInfo.CurrentLanguage;
cl = cl == "zh" ? "ko" : cl == "ko" ? "zh" : cl;
CB.DataSource = Util.GetCountryRegionList(type, cl);
if (index > 0 && index < CB.Items.Count)
@@ -893,7 +891,7 @@ public static void SetCountrySubRegion(ComboBox CB, string type)
private void ChangeMainLanguage(object sender, EventArgs e)
{
if (CB_MainLanguage.SelectedIndex < 8)
CurrentLanguage = GameInfo.Language2Char((uint)CB_MainLanguage.SelectedIndex);
CurrentLanguage = GameLanguage.Language2Char(CB_MainLanguage.SelectedIndex);
// Set the culture (makes it easy to pass language to other forms)
Settings.Default.Language = CurrentLanguage;
@@ -914,10 +912,12 @@ private void ChangeMainLanguage(object sender, EventArgs e)
}
}
private static void InitializeStrings()
private void InitializeStrings()
{
string l = CurrentLanguage;
GameInfo.Strings = GameInfo.GetStrings(l);
if (C_SAV.SAV != null)
GameInfo.FilteredSources = new FilteredGameDataSource(C_SAV.SAV, GameInfo.Sources, HaX);
// Update Legality Strings
Task.Run(() => {

View File

@@ -1,45 +0,0 @@
namespace PKHeX.WinForms
{
public enum ProgramLanguage
{
/// <summary>
/// Japanese
/// </summary>
,
/// <summary>
/// English
/// </summary>
English,
/// <summary>
/// French
/// </summary>
Français,
/// <summary>
/// Italian
/// </summary>
Italiano,
/// <summary>
/// German
/// </summary>
Deutsch,
/// <summary>
/// Spanish
/// </summary>
Español,
/// <summary>
/// Korean
/// </summary>
,
/// <summary>
/// Chinese
/// </summary>
,
}
}

View File

@@ -99,7 +99,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<LangVersion>7.2</LangVersion>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono-Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
@@ -111,7 +111,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<LangVersion>7.2</LangVersion>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Mono-Release|AnyCPU'">
<OutputPath>bin\Mono-Release\</OutputPath>
@@ -122,7 +122,7 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<LangVersion>7.2</LangVersion>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ClickOnce|x86'">
<OutputPath>bin\x86\ClickOnce\</OutputPath>
@@ -145,7 +145,7 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
<NoWin32Manifest>true</NoWin32Manifest>
<LangVersion>7.2</LangVersion>
<LangVersion>7.2</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -277,7 +277,6 @@
<DependentUpon>PKMEditor.cs</DependentUpon>
</Compile>
<Compile Include="MainWindow\PluginLoader.cs" />
<Compile Include="MainWindow\ProgramLanguage.cs" />
<Compile Include="Misc\About.cs">
<SubType>Form</SubType>
</Compile>

View File

@@ -33,7 +33,7 @@ public class PKMPreview
public string Ball => Get(Strings.balllist, pkm.Ball);
public string OT => pkm.OT_Name;
public string Version => Get(Strings.gamelist, pkm.Version);
public string OTLang => Get(Strings.gamelanguages, pkm.Language) ?? $"UNK {pkm.Language}";
public string OTLang => Get(GameDataSource.Languages, pkm.Language) ?? $"UNK {pkm.Language}";
public string Legal { get { var la = new LegalityAnalysis(pkm); return la.Parsed ? la.Valid.ToString() : "-"; } }
public string CountryID => pkm.Format > 5 ? pkm.Country.ToString() : "N/A";
public string RegionID => pkm.Format > 5 ? pkm.Region.ToString() : "N/A";

View File

@@ -182,7 +182,7 @@ private void B_Cancel_Click(object sender, EventArgs e)
private void GetLangStrings()
{
var strings = GameInfo.Strings.Memories;
var strings = GameInfo.FilteredSources.Source.Memories;
CB_OTMemory.InitializeBinding();
CB_CTMemory.InitializeBinding();
CB_OTMemory.DataSource = new BindingSource(strings.Memory, null);
@@ -207,7 +207,7 @@ private void UpdateMemoryDisplay(object sender)
{
int memory = WinFormsUtil.GetIndex((ComboBox) sender);
var memIndex = Memories.GetMemoryArgType(memory);
var argvals = GameInfo.Strings.Memories.GetArgumentStrings(memIndex);
var argvals = GameInfo.Sources.Memories.GetArgumentStrings(memIndex);
if (sender == CB_CTMemory)
{
CB_CTVar.InitializeBinding();

View File

@@ -432,7 +432,7 @@ private void SetAbilityList()
int formnum = CB_Form.SelectedIndex;
int[] abils = PersonalTable.AO.GetAbilities(species, formnum);
CB_Ability.DataSource = GameInfo.Strings.GetAbilityDataSource(abils);
CB_Ability.DataSource = GameInfo.FilteredSources.GetAbilityList(abils, 6);
CB_Ability.SelectedIndex = newabil < 3 ? newabil : 0;
}

View File

@@ -105,7 +105,7 @@ private void HandleSpecialFlags()
private string[] GetStringList(string type)
{
gamePrefix = GetResourceSuffix(SAV.Version);
return GameInfo.GetStrings(gamePrefix, GameInfo.CurrentLanguage, type);
return GameLanguage.GetStrings(gamePrefix, GameInfo.CurrentLanguage, type);
}
private static string GetResourceSuffix(GameVersion ver)

View File

@@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
using static PKHeX.Core.MessageStrings;
namespace PKHeX.WinForms
{
@@ -249,7 +247,7 @@ private void LoadSAV(object sender, string path)
private static string[] GetStringList(GameVersion game, string type)
{
var gamePrefix = GetGameFilePrefix(game);
return GameInfo.GetStrings(gamePrefix, GameInfo.CurrentLanguage, type);
return GameLanguage.GetStrings(gamePrefix, GameInfo.CurrentLanguage, type);
}
private static string GetGameFilePrefix(GameVersion game)