diff --git a/PKHeX.Core/Editing/PKM/EditPKMUtil.cs b/PKHeX.Core/Editing/PKM/EditPKMUtil.cs index 6eaa35fdf..cb81e42cc 100644 --- a/PKHeX.Core/Editing/PKM/EditPKMUtil.cs +++ b/PKHeX.Core/Editing/PKM/EditPKMUtil.cs @@ -22,12 +22,6 @@ public static List GetSuggestionMessage(PKM pkm, int level, int location return suggestion; } - public static IReadOnlyList GetAbilityList(PKM pkm) - { - var abils = pkm.PersonalInfo.Abilities; - return GameInfo.GetAbilityList(abils, pkm.Format); - } - /// /// Applies junk data to a , which is preferable to a completely empty entity. /// diff --git a/PKHeX.Core/Editing/ShowdownSet.cs b/PKHeX.Core/Editing/ShowdownSet.cs index 95db9c8dd..c1a3ae976 100644 --- a/PKHeX.Core/Editing/ShowdownSet.cs +++ b/PKHeX.Core/Editing/ShowdownSet.cs @@ -245,7 +245,7 @@ private bool ParseEntry(string identifier, string value) /// Gets the localized Text representation of the set details. /// /// 2 character language code - public string LocalizedText(string lang) => LocalizedText(GameInfo.Language(lang)); + public string LocalizedText(string lang) => LocalizedText(GameLanguage.GetLanguageIndex(lang)); /// /// Gets the localized Text representation of the set details. diff --git a/PKHeX.Core/Game/GameStrings/FilteredGameDataSource.cs b/PKHeX.Core/Game/GameStrings/FilteredGameDataSource.cs new file mode 100644 index 000000000..56c0c2788 --- /dev/null +++ b/PKHeX.Core/Game/GameStrings/FilteredGameDataSource.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PKHeX.Core +{ + /// + /// sensitive provider for data sources. + /// + 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(); + } + + 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 Moves; + public readonly IReadOnlyList Balls; + public readonly IReadOnlyList Games; + public readonly IReadOnlyList Items; + public readonly IReadOnlyList Species; + public readonly IReadOnlyList Languages; + public readonly IReadOnlyList Abilities; + public readonly IReadOnlyList Natures; + public readonly IReadOnlyList G4EncounterTypes; + public readonly IReadOnlyList ConsoleRegions = GameDataSource.Regions; + + public IReadOnlyList GetAbilityList(PKM pkm) + { + var abils = pkm.PersonalInfo.Abilities; + int format = pkm.Format; + return GetAbilityList(abils, format); + } + + public IReadOnlyList 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)" }; + } +} diff --git a/PKHeX.Core/Game/GameStrings/GameDataSource.cs b/PKHeX.Core/Game/GameStrings/GameDataSource.cs new file mode 100644 index 000000000..be2e35f01 --- /dev/null +++ b/PKHeX.Core/Game/GameStrings/GameDataSource.cs @@ -0,0 +1,284 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PKHeX.Core +{ + /// + /// Bundles raw string inputs into lists that can be used in data binding. + /// + public class GameDataSource + { + public static readonly IReadOnlyList Regions = Util.GetCSVUnsortedCBList("regions3ds"); + public static readonly IReadOnlyList 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 SpeciesDataSource; + public readonly IReadOnlyList BallDataSource; + public readonly IReadOnlyList NatureDataSource; + public readonly IReadOnlyList AbilityDataSource; + public readonly IReadOnlyList VersionDataSource; + public readonly IReadOnlyList LegalMoveDataSource; + public readonly IReadOnlyList HaXMoveDataSource; + public readonly IReadOnlyList EncounterTypeDataSource; + + private IReadOnlyList MetGen2 { get; set; } + private IReadOnlyList MetGen3 { get; set; } + private IReadOnlyList MetGen3CXD { get; set; } + private IReadOnlyList MetGen4 { get; set; } + private IReadOnlyList MetGen5 { get; set; } + private IReadOnlyList MetGen6 { get; set; } + private IReadOnlyList MetGen7 { get; set; } + private IReadOnlyList MetGen7GG { get; set; } + + private IReadOnlyList 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 GetItemDataSource(GameVersion game, int generation, int MaxItemID, IEnumerable 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()); + } + + /// + /// Fetches a Met Location list for a that has been transferred away from and overwritten. + /// + /// Origin version + /// Current savefile generation + /// True if an egg location list, false if a regular met location list + /// Met location list + public IReadOnlyList 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); + } + + /// + /// Fetches a Met Location list for a that has been transferred away from and overwritten. + /// + /// Origin version + /// Current savefile generation + /// Met location list + private IReadOnlyList 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(); + } + + public static IReadOnlyList 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; + } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Game/GameStrings/GameInfo.cs b/PKHeX.Core/Game/GameStrings/GameInfo.cs index d23835ed2..36b9eeac6 100644 --- a/PKHeX.Core/Game/GameStrings/GameInfo.cs +++ b/PKHeX.Core/Game/GameStrings/GameInfo.cs @@ -1,59 +1,43 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace PKHeX.Core { + /// + /// Shared instance for fetching data + /// 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 GenderSymbolUnicode = new[] {"♂", "♀", "-"}; public static readonly IReadOnlyList 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 ItemDataSource => Strings.ItemDataSource; - public static IReadOnlyList SpeciesDataSource => Strings.SpeciesDataSource; - public static IReadOnlyList BallDataSource => Strings.BallDataSource; - public static IReadOnlyList NatureDataSource => Strings.NatureDataSource; - public static IReadOnlyList AbilityDataSource => Strings.AbilityDataSource; - public static IReadOnlyList VersionDataSource => Strings.VersionDataSource; - public static IReadOnlyList LegalMoveDataSource => Strings.LegalMoveDataSource; - public static IReadOnlyList HaXMoveDataSource => Strings.HaXMoveDataSource; - public static IReadOnlyList MoveDataSource => Strings.MoveDataSource; - public static IReadOnlyList EncounterTypeDataSource => Strings.EncounterTypeDataSource; - public static IReadOnlyList Regions => GameStrings.Regions; + public static IReadOnlyList ItemDataSource => FilteredSources.Items; + public static IReadOnlyList SpeciesDataSource => Sources.SpeciesDataSource; + public static IReadOnlyList BallDataSource => Sources.BallDataSource; + public static IReadOnlyList NatureDataSource => Sources.NatureDataSource; + public static IReadOnlyList AbilityDataSource => Sources.AbilityDataSource; + public static IReadOnlyList VersionDataSource => Sources.VersionDataSource; + public static IReadOnlyList MoveDataSource => Sources.HaXMoveDataSource; + public static IReadOnlyList EncounterTypeDataSource => Sources.EncounterTypeDataSource; + public static IReadOnlyList Regions => GameDataSource.Regions; - public static IReadOnlyList LanguageDataSource(int gen) => GameStrings.LanguageDataSource(gen); - - public static IReadOnlyList GetAbilityList(int[] abils, int format) - { - if (format == 3 && abils[1] == abils[0]) - abils = new[] { abils[0] }; - return Strings.GetAbilityDataSource(abils); - } - - /// - /// Gets the location names array for a specified generation. - /// - /// Generation to get location names for. - /// BankID used to choose the text bank. - /// Version of origin - /// List of location names. - private static IReadOnlyList 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(); - } - } - - private static IReadOnlyList 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(); - } - } - - private static IReadOnlyList 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(); - } - } - - private static IReadOnlyList 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(); - } - } - - private static IReadOnlyList 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(); - } - } - - private static IReadOnlyList 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(); - } - } + public static IReadOnlyList LanguageDataSource(int gen) => GameDataSource.LanguageDataSource(gen); /// /// Gets the location name for the specified parameters. @@ -180,44 +70,7 @@ private static IReadOnlyList GetLocationNames7GG(int bankID) /// Location name 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); } /// @@ -229,7 +82,7 @@ public static string GetLocationName(bool eggmet, int locval, int format, int ge /// Consumable list of met locations public static IReadOnlyList GetLocationList(GameVersion version, int pkmFormat, bool egg = false) { - return Strings.GetLocationList(version, pkmFormat, egg); + return Sources.GetLocationList(version, pkmFormat, egg); } } } diff --git a/PKHeX.Core/Game/GameStrings/GameLanguage.cs b/PKHeX.Core/Game/GameStrings/GameLanguage.cs new file mode 100644 index 000000000..24c0b15c3 --- /dev/null +++ b/PKHeX.Core/Game/GameStrings/GameLanguage.cs @@ -0,0 +1,94 @@ +using System; + +namespace PKHeX.Core +{ + /// + /// Language code & string asset loading. + /// + 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; + } + + /// + /// Language codes supported for loading string resources + /// + /// + private static readonly string[] LanguageCodes = { "ja", "en", "fr", "it", "de", "es", "ko", "zh", "zh2" }; + + /// + /// Pokétransporter location names, ordered per index of + /// + 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 + { + /// + /// Japanese + /// + 日本語, + + /// + /// English + /// + English, + + /// + /// French + /// + Français, + + /// + /// Italian + /// + Italiano, + + /// + /// German + /// + Deutsch, + + /// + /// Spanish + /// + Español, + + /// + /// Korean + /// + 한국어, + + /// + /// Chinese + /// + 中文, + } +} \ No newline at end of file diff --git a/PKHeX.Core/Game/GameStrings/GameStrings.cs b/PKHeX.Core/Game/GameStrings/GameStrings.cs index 03732f780..09c286859 100644 --- a/PKHeX.Core/Game/GameStrings/GameStrings.cs +++ b/PKHeX.Core/Game/GameStrings/GameStrings.cs @@ -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 Species => specieslist; @@ -33,16 +34,14 @@ public class GameStrings : IBasicStrings public IReadOnlyList Types => types; public IReadOnlyList 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 Regions = Util.GetCSVUnsortedCBList("regions3ds"); - private static readonly IReadOnlyList 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 ItemDataSource { get; private set; } - public IReadOnlyList SpeciesDataSource { get; private set; } - public IReadOnlyList BallDataSource { get; private set; } - public IReadOnlyList NatureDataSource { get; private set; } - public IReadOnlyList AbilityDataSource { get; private set; } - public IReadOnlyList VersionDataSource { get; private set; } - public IReadOnlyList LegalMoveDataSource { get; private set; } - public IReadOnlyList HaXMoveDataSource { get; private set; } - public IReadOnlyList MoveDataSource { get; set; } - public IReadOnlyList EncounterTypeDataSource { get; private set; } - - private IReadOnlyList MetGen2 { get; set; } - private IReadOnlyList MetGen3 { get; set; } - private IReadOnlyList MetGen3CXD { get; set; } - private IReadOnlyList MetGen4 { get; set; } - private IReadOnlyList MetGen5 { get; set; } - private IReadOnlyList MetGen6 { get; set; } - private IReadOnlyList MetGen7 { get; set; } - private IReadOnlyList 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() + /// + /// Gets the location name for the specified parameters. + /// + /// Location is from the + /// Location value + /// Current + /// of origin + /// Current GameVersion (only applicable for differentiation) + /// Location name + 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 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 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]; } /// - /// Fetches a Met Location list for a that has been transferred away from and overwritten. + /// Gets the location names array for a specified generation. /// - /// Origin version - /// Current savefile generation - /// True if an egg location list, false if a regular met location list - /// Met location list - public IReadOnlyList GetLocationList(GameVersion version, int currentGen, bool egg = false) + /// Generation to get location names for. + /// BankID used to choose the text bank. + /// Version of origin + /// List of location names. + public IReadOnlyList 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(); } - - return GetLocationListModified(version, currentGen); } - /// - /// Fetches a Met Location list for a that has been transferred away from and overwritten. - /// - /// Origin version - /// Current savefile generation - /// Met location list - private IReadOnlyList GetLocationListModified(GameVersion version, int currentGen) + private IReadOnlyList 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(); } - - 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(); } - public static IReadOnlyList LanguageDataSource(int gen) + public IReadOnlyList 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(); + } } - public IReadOnlyList GetAbilityDataSource(IEnumerable abils) + public IReadOnlyList 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(); + } + } + + public IReadOnlyList 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(); + } + } + + public IReadOnlyList 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(); + } } } } \ No newline at end of file diff --git a/PKHeX.Core/Util/DataUtil.cs b/PKHeX.Core/Util/DataUtil.cs index 9c087b469..bd8dc68ec 100644 --- a/PKHeX.Core/Util/DataUtil.cs +++ b/PKHeX.Core/Util/DataUtil.cs @@ -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 GetCountryRegionList(string textfile, string lang) { diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs index e7931f969..1f353d8ce 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs @@ -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); } } } diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 6d35896e0..1a76f13aa 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -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(() => { diff --git a/PKHeX.WinForms/MainWindow/ProgramLanguage.cs b/PKHeX.WinForms/MainWindow/ProgramLanguage.cs deleted file mode 100644 index 534c252e4..000000000 --- a/PKHeX.WinForms/MainWindow/ProgramLanguage.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace PKHeX.WinForms -{ - public enum ProgramLanguage - { - /// - /// Japanese - /// - 日本語, - - /// - /// English - /// - English, - - /// - /// French - /// - Français, - - /// - /// Italian - /// - Italiano, - - /// - /// German - /// - Deutsch, - - /// - /// Spanish - /// - Español, - - /// - /// Korean - /// - 한국어, - - /// - /// Chinese - /// - 中文, - } -} \ No newline at end of file diff --git a/PKHeX.WinForms/PKHeX.WinForms.csproj b/PKHeX.WinForms/PKHeX.WinForms.csproj index a58fe7d8e..992cb3f34 100644 --- a/PKHeX.WinForms/PKHeX.WinForms.csproj +++ b/PKHeX.WinForms/PKHeX.WinForms.csproj @@ -99,7 +99,7 @@ prompt MinimumRecommendedRules.ruleset true - 7.2 + 7.2 true @@ -111,7 +111,7 @@ prompt MinimumRecommendedRules.ruleset true - 7.2 + 7.2 bin\Mono-Release\ @@ -122,7 +122,7 @@ prompt MinimumRecommendedRules.ruleset true - 7.2 + 7.2 bin\x86\ClickOnce\ @@ -145,7 +145,7 @@ MinimumRecommendedRules.ruleset true true - 7.2 + 7.2 @@ -277,7 +277,6 @@ PKMEditor.cs - Form diff --git a/PKHeX.WinForms/Subforms/Misc/PKMPreview.cs b/PKHeX.WinForms/Subforms/Misc/PKMPreview.cs index edfa9b115..4b266e2d3 100644 --- a/PKHeX.WinForms/Subforms/Misc/PKMPreview.cs +++ b/PKHeX.WinForms/Subforms/Misc/PKMPreview.cs @@ -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"; diff --git a/PKHeX.WinForms/Subforms/PKM Editors/MemoryAmie.cs b/PKHeX.WinForms/Subforms/PKM Editors/MemoryAmie.cs index e8a5958dd..16354af72 100644 --- a/PKHeX.WinForms/Subforms/PKM Editors/MemoryAmie.cs +++ b/PKHeX.WinForms/Subforms/PKM Editors/MemoryAmie.cs @@ -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(); diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs index 8620e2e4e..de94faeb5 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs @@ -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; } diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_EventFlags.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_EventFlags.cs index 5d135dad9..50ef60837 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_EventFlags.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_EventFlags.cs @@ -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) diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_EventWork.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_EventWork.cs index b6eb45ff0..7f08d3ee7 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_EventWork.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_EventWork.cs @@ -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)