Deferred Humanization of LegalityAnalysis (#4531)

This commit is contained in:
Kurt 2025-07-27 20:54:58 -05:00 committed by GitHub
parent a5cdb0e27c
commit 13a4d472bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
179 changed files with 6795 additions and 5477 deletions

View File

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace PKHeX.Core;
@ -14,8 +13,16 @@ public sealed record BattleTemplateLocalization(GameStrings Strings, BattleTempl
public const string DefaultLanguage = GameLanguage.DefaultLanguage; // English
private static readonly Dictionary<string, BattleTemplateLocalization> Cache = new();
private static readonly BattleTemplateConfigContext Context = new(LocalizationStorage<BattleTemplateConfig>.Options);
public static readonly LocalizationStorage<BattleTemplateConfig> ConfigCache = new("battle", Context.BattleTemplateConfig);
public static readonly BattleTemplateLocalization Default = GetLocalization(DefaultLanguage);
/// <summary>
/// Gets the localization for the requested language.
/// </summary>
/// <param name="language">Language code</param>
public static BattleTemplateConfig GetConfig(string language) => ConfigCache.Get(language);
/// <param name="language"><see cref="LanguageID"/> index</param>
/// <inheritdoc cref="GetLocalization(string)"/>
public static BattleTemplateLocalization GetLocalization(LanguageID language) =>
@ -37,17 +44,6 @@ public static BattleTemplateLocalization GetLocalization(string language)
return result;
}
private static string GetJson(string language) => Util.GetStringResource($"battle_{language}.json");
private static BattleTemplateConfigContext GetContext() => new();
private static BattleTemplateConfig GetConfig(string language)
{
var text = GetJson(language);
var result = JsonSerializer.Deserialize(text, GetContext().BattleTemplateConfig)
?? throw new JsonException($"Failed to deserialize {nameof(BattleTemplateConfig)} for {language}");
return result;
}
/// <summary>
/// Force loads all localizations.
/// </summary>

View File

@ -31,11 +31,12 @@ public FilteredGameDataSource(SaveFile sav, GameDataSource source, bool HaX = fa
var gamelist = GameUtil.GetVersionsWithinRange(sav, sav.Generation).ToList();
Games = Source.VersionDataSource.Where(g => gamelist.Contains((GameVersion)g.Value) || g.Value == 0).ToList();
Languages = GameDataSource.LanguageDataSource(sav.Generation);
Languages = Source.LanguageDataSource(sav.Generation);
Balls = Source.BallDataSource.Where(b => b.Value <= sav.MaxBallID).ToList();
Abilities = Source.AbilityDataSource.Where(a => a.Value <= sav.MaxAbilityID).ToList();
G4GroundTiles = Source.GroundTileDataSource;
ConsoleRegions = Source.Regions;
Natures = Source.NatureDataSource;
}
@ -113,7 +114,7 @@ private static List<ComboItem> GetMovesWithoutDummy(IReadOnlyList<ComboItem> leg
public readonly IReadOnlyList<ComboItem> Abilities;
public readonly IReadOnlyList<ComboItem> Natures;
public readonly IReadOnlyList<ComboItem> G4GroundTiles;
public readonly IReadOnlyList<ComboItem> ConsoleRegions = GameDataSource.Regions;
public readonly IReadOnlyList<ComboItem> ConsoleRegions;
private const char HiddenAbilitySuffix = 'H';
private const char AbilityIndexSuffix = '1';

View File

@ -11,30 +11,24 @@ public sealed class GameDataSource
/// <summary>
/// List of <see cref="Region3DSIndex"/> values to display.
/// </summary>
public static readonly IReadOnlyList<ComboItem> Regions =
[
new ("Japan (日本)", 0),
new ("Americas (NA/SA)", 1),
new ("Europe (EU/AU)", 2),
new ("China (中国大陆)", 4),
new ("Korea (한국)", 5),
new ("Taiwan (香港/台灣)", 6),
];
public readonly IReadOnlyList<ComboItem> Regions;
/// <summary>
/// List of <see cref="LanguageID"/> values to display.
/// </summary>
private static readonly ComboItem[] LanguageList =
private readonly ComboItem[] LanguageList;
private static ReadOnlySpan<byte> LanguageIDs =>
[
new ("JPN (日本語)", (int)LanguageID.Japanese),
new ("ENG (English)", (int)LanguageID.English),
new ("FRE (Français)", (int)LanguageID.French),
new ("ITA (Italiano)", (int)LanguageID.Italian),
new ("GER (Deutsch)", (int)LanguageID.German),
new ("ESP (Español)", (int)LanguageID.Spanish),
new ("KOR (한국어)", (int)LanguageID.Korean),
new ("CHS (简体中文)", (int)LanguageID.ChineseS),
new ("CHT (繁體中文)", (int)LanguageID.ChineseT),
(byte)LanguageID.Japanese,
(byte)LanguageID.English,
(byte)LanguageID.French,
(byte)LanguageID.Italian,
(byte)LanguageID.German,
(byte)LanguageID.Spanish,
(byte)LanguageID.Korean,
(byte)LanguageID.ChineseS,
(byte)LanguageID.ChineseT,
];
/// <summary>
@ -42,7 +36,7 @@ public sealed class GameDataSource
/// </summary>
/// <param name="generation">Generation to get the language list for.</param>
/// <returns>List of languages to display.</returns>
public static IReadOnlyList<ComboItem> LanguageDataSource(byte generation) => generation switch
public IReadOnlyList<ComboItem> LanguageDataSource(byte generation) => generation switch
{
3 => LanguageList[..6], // No Korean+
< 7 => LanguageList[..7], // No Chinese+
@ -57,6 +51,8 @@ public GameDataSource(GameStrings s)
NatureDataSource = Util.GetCBList(s.natures);
AbilityDataSource = Util.GetCBList(s.abilitylist);
GroundTileDataSource = Util.GetUnsortedCBList(s.groundtiletypes, GroundTileTypeExtensions.ValidTileTypes);
Regions = Util.GetUnsortedCBList(s.console3ds, Locale3DS.DefinedLocales);
LanguageList = Util.GetUnsortedCBList(s.languageNames, LanguageIDs);
var moves = Util.GetCBList(s.movelist);
HaXMoveDataSource = moves;

View File

@ -47,10 +47,10 @@ public static string GetVersionName(GameVersion version)
public static IReadOnlyList<ComboItem> VersionDataSource => Sources.VersionDataSource;
public static IReadOnlyList<ComboItem> MoveDataSource => Sources.HaXMoveDataSource;
public static IReadOnlyList<ComboItem> GroundTileDataSource => Sources.GroundTileDataSource;
public static IReadOnlyList<ComboItem> Regions => GameDataSource.Regions;
public static IReadOnlyList<ComboItem> Regions => Sources.Regions;
public static IReadOnlyList<ComboItem> LanguageDataSource(byte generation)
=> GameDataSource.LanguageDataSource(generation);
=> Sources.LanguageDataSource(generation);
/// <summary>
/// Gets the location name for the specified parameters.

View File

@ -27,8 +27,11 @@ public sealed class GameStrings : IBasicStrings
public readonly string[] wallpapernames, puffs, walkercourses;
public readonly string[] uggoods, ugspheres, ugtraps, ugtreasures;
public readonly string[] seals, accessories, backdrops, poketchapps;
public readonly string[] console3ds, languageNames;
private readonly string LanguageFilePrefix;
public readonly RibbonStrings Ribbons;
public LanguageID Language { get; }
public string EggName { get; }
public IReadOnlyList<string> Species => specieslist;
@ -59,6 +62,7 @@ internal GameStrings(string langFilePrefix)
Language = GameLanguage.GetLanguage(LanguageFilePrefix = langFilePrefix);
ribbons = Get("ribbons");
Ribbons = new(ribbons);
// Past Generation strings
g3items = Get("ItemsG3");
@ -124,6 +128,8 @@ internal GameStrings(string langFilePrefix)
accessories = Get("accessories");
backdrops = Get("backdrops");
poketchapps = Get("poketchapps");
console3ds = Get("console3ds");
languageNames = Get("language");
EggName = specieslist[0];
Gen4 = Get4("hgss");
@ -784,11 +790,25 @@ private string[] GetItemStrings3(GameVersion game)
return g3items;
var g3ItemsWithEBerry = (string[])g3items.Clone();
g3ItemsWithEBerry[175] = EReaderBerrySettings.DisplayName;
g3ItemsWithEBerry[175] = GetEnigmaBerryName3(Language, EReaderBerrySettings.Name);
return g3ItemsWithEBerry;
}
}
private static string GetEnigmaBerryName3(LanguageID language, string berryName) => string.Format(language switch
{
Japanese => "{0}のみ",
English => "{0} BERRY",
German => "{0}BEERE",
French => "BAIE {0}",
Italian => "BACCA{0}",
Spanish => "BAYA {0}",
Korean => "{0}열매",
ChineseS => "{0}果",
ChineseT => "{0}果",
_ => throw new ArgumentOutOfRangeException(nameof(language), language, null),
}, berryName);
/// <summary>
/// Gets the location name for the specified parameters.
/// </summary>

View File

@ -4,6 +4,8 @@
namespace PKHeX.Core.Bulk;
public readonly record struct BulkCheckResult(CheckResult Result, string Comment);
/// <summary>
/// Analyzes content within a <see cref="SaveFile"/> for overall <see cref="PKM"/> legality analysis.
/// </summary>
@ -12,7 +14,7 @@ public sealed class BulkAnalysis
public readonly IReadOnlyList<SlotCache> AllData;
public readonly IReadOnlyList<LegalityAnalysis> AllAnalysis;
public readonly ITrainerInfo Trainer;
public readonly List<CheckResult> Parse = [];
public readonly List<BulkCheckResult> Parse = [];
public readonly Dictionary<ulong, SlotCache> Trackers = [];
public readonly bool Valid;
@ -41,7 +43,7 @@ public BulkAnalysis(SaveFile sav, BulkAnalysisSettings settings)
CloneFlags = new bool[AllData.Count];
ScanAll();
Valid = Parse.Count == 0 || Parse.TrueForAll(static z => z.Valid);
Valid = Parse.Count == 0 || Parse.TrueForAll(static z => z.Result.Valid);
}
// Remove things that aren't actual stored data, or already flagged by legality checks.
@ -79,21 +81,21 @@ private void ScanAll()
/// <summary>
/// Adds a new entry to the <see cref="Parse"/> list.
/// </summary>
public void AddLine(SlotCache first, SlotCache second, string msg, CheckIdentifier i, Severity s = Severity.Invalid)
public void AddLine(SlotCache first, SlotCache second, LegalityCheckResultCode msg, CheckIdentifier i, Severity s = Severity.Invalid)
{
var c = $"{msg}{Environment.NewLine}{GetSummary(first)}{Environment.NewLine}{GetSummary(second)}{Environment.NewLine}";
var chk = new CheckResult(s, i, c);
Parse.Add(chk);
var line = $"{msg}{Environment.NewLine}{GetSummary(first)}{Environment.NewLine}{GetSummary(second)}{Environment.NewLine}";
var chk = CheckResult.Get(s, i, msg);
Parse.Add(new(chk, line));
}
/// <summary>
/// Adds a new entry to the <see cref="Parse"/> list.
/// </summary>
public void AddLine(SlotCache first, string msg, CheckIdentifier i, Severity s = Severity.Invalid)
public void AddLine(SlotCache first, LegalityCheckResultCode msg, CheckIdentifier i, Severity s = Severity.Invalid)
{
var c = $"{msg}{Environment.NewLine}{GetSummary(first)}{Environment.NewLine}";
var chk = new CheckResult(s, i, c);
Parse.Add(chk);
var line = $"{msg}{Environment.NewLine}{GetSummary(first)}{Environment.NewLine}";
var chk = CheckResult.Get(s, i, msg);
Parse.Add(new(chk, line));
}
private static LegalityAnalysis[] GetIndividualAnalysis(ReadOnlySpan<SlotCache> list)

View File

@ -61,10 +61,10 @@ private static void VerifyECShare(BulkAnalysis input, CombinedReference pr, Comb
{
if (ca.Info.Generation != gen)
{
input.AddLine(ps, cs, "EC sharing across generations detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingEncryptionConstantGenerationDifferent, ident);
return;
}
input.AddLine(ps, cs, "EC sharing for 3DS-onward origin detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingEncryptionConstantGenerationSame, ident);
return;
}
@ -76,7 +76,7 @@ private static void VerifyECShare(BulkAnalysis input, CombinedReference pr, Comb
if (eggMysteryCurrent != eggMysteryPrevious)
{
input.AddLine(ps, cs, "EC sharing across RNG encounters detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingEncryptionConstantEncounterType, ident);
}
}
}

View File

@ -51,7 +51,7 @@ private static void CheckDuplicateOwnedGifts(BulkAnalysis input)
var grp = tidGroup[0];
var first = grp[0].Slot;
var second = grp[1].Slot;
input.AddLine(first, second, $"Receipt of the same egg mystery gifts detected: {dupe.Key}", Encounter);
input.AddLine(first, second, LegalityCheckResultCode.BulkDuplicateMysteryGiftEggReceived, Encounter);
}
}

View File

@ -58,14 +58,14 @@ private static void VerifyPIDShare(BulkAnalysis input, CombinedReference pr, Com
if (ca.Info.Generation != gen)
{
input.AddLine(ps, cs, "PID sharing across generations detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingPIDGenerationDifferent, ident);
return;
}
bool gbaNDS = gen is 3 or 4 or 5;
if (!gbaNDS)
{
input.AddLine(ps, cs, "PID sharing for 3DS-onward origin detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingPIDGenerationSame, ident);
return;
}
@ -77,7 +77,7 @@ private static void VerifyPIDShare(BulkAnalysis input, CombinedReference pr, Com
if (eggMysteryCurrent != eggMysteryPrevious)
{
input.AddLine(ps, cs, "PID sharing across RNG encounters detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingPIDEncounterType, ident);
}
}
}

View File

@ -68,7 +68,7 @@ private static bool VerifyIDReuse(BulkAnalysis input, SlotCache ps, LegalityAnal
// Trainer-ID-SID16 should only occur for one version
if (IsSharedVersion(pp, pa, cp, ca))
{
input.AddLine(ps, cs, "TID sharing across versions detected.", ident);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingTrainerVersion, ident);
return true;
}
@ -76,7 +76,7 @@ private static bool VerifyIDReuse(BulkAnalysis input, SlotCache ps, LegalityAnal
if (pp.OriginalTrainerName != cp.OriginalTrainerName)
{
var severity = ca.Info.Generation == 4 ? Severity.Fishy : Severity.Invalid;
input.AddLine(ps, cs, "TID sharing across different trainer names detected.", ident, severity);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkSharingTrainerIDs, ident, severity);
}
return false;

View File

@ -1,6 +1,6 @@
using System;
using static PKHeX.Core.CheckIdentifier;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core.Bulk;
@ -44,7 +44,7 @@ private static void Verify(BulkAnalysis input, SlotCache cs, LegalityAnalysis la
var shouldBe0 = tr.IsFromTrainer(pk);
byte expect = shouldBe0 ? (byte)0 : (byte)1;
if (!HistoryVerifier.IsHandlerStateCorrect(la.EncounterOriginal, pk, current, expect))
input.AddLine(cs, LTransferCurrentHandlerInvalid, Trainer);
input.AddLine(cs, TransferCurrentHandlerInvalid, Trainer);
if (current == 1)
CheckHandlingTrainerEquals(input, pk, tr, cs);
@ -58,14 +58,14 @@ private static void CheckHandlingTrainerEquals(BulkAnalysis data, PKM pk, SaveFi
ht = ht[..len];
if (!ht.SequenceEqual(tr.OT))
data.AddLine(cs, LTransferHTMismatchName, Trainer);
data.AddLine(cs, TransferHandlerMismatchName, Trainer);
if (pk.HandlingTrainerGender != tr.Gender)
data.AddLine(cs, LTransferHTMismatchGender, Trainer);
data.AddLine(cs, TransferHandlerMismatchGender, Trainer);
// If the format exposes a language, check if it matches.
// Can be mismatched as the game only checks OT/Gender equivalence -- if it matches, don't update everything else.
// Statistically unlikely that players will play in different languages, but it's technically possible.
if (pk is IHandlerLanguage h && h.HandlingTrainerLanguage != tr.Language)
data.AddLine(cs, LTransferHTMismatchLanguage, Trainer, Severity.Fishy);
data.AddLine(cs, TransferHandlerMismatchLanguage, Trainer, Severity.Fishy);
}
}

View File

@ -38,7 +38,7 @@ private static void CheckClones(BulkAnalysis input)
}
input.SetIsClone(i, true);
input.AddLine(ps, cs, "Clone detected (Details).", Encounter);
input.AddLine(ps, cs, LegalityCheckResultCode.BulkCloneDetectedDetails, Encounter);
}
}
@ -54,7 +54,7 @@ private static void CheckClonedTrackerHOME(BulkAnalysis input, IHomeTrack home,
private static void CheckTrackerPresent(BulkAnalysis input, SlotCache cs, ulong tracker)
{
if (input.Trackers.TryGetValue(tracker, out var clone))
input.AddLine(cs, clone, "Clone detected (Duplicate Tracker).", Encounter);
input.AddLine(cs, clone, LegalityCheckResultCode.BulkCloneDetectedTracker, Encounter);
else
input.Trackers.Add(tracker, cs);
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -45,7 +45,7 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
// Looks like we might have a good enough match. Check if this is really a good match.
info.EncounterMatch = enc;
if (e.Comment.Length != 0)
if (e.Result != Valid)
info.Parse.Add(e);
if (!VerifySecondaryChecks(pk, info, encounter))
continue;
@ -63,7 +63,7 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
continue;
// We ran out of possible encounters without finding a suitable match; add a message indicating that the encounter is not a complete match.
info.Parse.Add(new CheckResult(Severity.Invalid, CheckIdentifier.Encounter, LEncInvalid));
info.Parse.Add(CheckResult.Get(Severity.Invalid, CheckIdentifier.Encounter, EncInvalid));
break;
}
@ -71,9 +71,9 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
if (manual != EncounterYieldFlag.None)
{
if (!info.FrameMatches) // if false, all valid RNG frame matches have already been consumed
info.Parse.Add(new CheckResult(ParseSettings.Settings.FramePattern.GetSeverity(info.Generation), CheckIdentifier.PID, LEncConditionBadRNGFrame));
info.Parse.Add(CheckResult.Get(ParseSettings.Settings.FramePattern.GetSeverity(info.Generation), CheckIdentifier.PID, EncConditionBadRNGFrame));
else if (!info.PIDIVMatches) // if false, all valid PID/IV matches have already been consumed
info.Parse.Add(new CheckResult(Severity.Invalid, CheckIdentifier.PID, LPIDTypeMismatch));
info.Parse.Add(CheckResult.Get(Severity.Invalid, CheckIdentifier.PID, PIDTypeMismatch));
}
}
@ -164,22 +164,22 @@ private static bool VerifySecondaryChecks(PKM pk, LegalInfo info, PeekEnumerator
private static void VerifyWithoutEncounter(PKM pk, LegalInfo info)
{
info.EncounterMatch = new EncounterInvalid(pk);
string hint = GetHintWhyNotFound(pk, info.EncounterMatch.Generation);
var hint = GetHintWhyNotFound(pk, info.EncounterMatch.Generation);
info.Parse.Add(new CheckResult(Severity.Invalid, CheckIdentifier.Encounter, hint));
info.Parse.Add(CheckResult.Get(Severity.Invalid, CheckIdentifier.Encounter, hint));
LearnVerifierRelearn.Verify(info.Relearn, info.EncounterOriginal, pk);
LearnVerifier.Verify(info.Moves, pk, info.EncounterMatch, info.EvoChainsAllGens);
}
private static string GetHintWhyNotFound(PKM pk, byte generation)
private static LegalityCheckResultCode GetHintWhyNotFound(PKM pk, byte generation)
{
if (WasGiftEgg(pk, generation, pk.EggLocation))
return LEncGift;
return EncGift;
if (WasEventEgg(pk, generation))
return LEncGiftEggEvent;
return EncGiftEggEvent;
if (WasEvent(pk, generation))
return LEncGiftNotFound;
return LEncInvalid;
return EncGiftNotFound;
return EncInvalid;
}
private static bool WasGiftEgg(PKM pk, byte generation, ushort eggLocation) => !pk.FatefulEncounter && generation switch

View File

@ -118,7 +118,8 @@ private bool SeekForward<TArea>(TArea[] areas)
var species = Entity.Species;
if (species is (int)Species.Dudunsparce or (int)Species.Maushold)
{
if (!EvolutionRestrictions.GetIsExpectedEvolveFormEC100(species, Entity.Form, Entity.EncryptionConstant % 100 == 0))
var expectRare = EvolutionRestrictions.IsEvolvedSpeciesFormRare(Entity.EncryptionConstant);
if (!EvolutionRestrictions.GetIsExpectedEvolveFormEC100(species, Entity.Form, expectRare))
return SeekMode.Reverse;
}
else if (EvolutionRestrictions.IsFormArgEvolution(species))

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
@ -9,15 +8,21 @@ namespace PKHeX.Core;
/// </summary>
public static class EncounterText
{
public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, bool verbose = false) => GetTextLines(enc, GameInfo.Strings, verbose);
private static EncounterDisplayContext GetContext(string language = GameLanguage.DefaultLanguage) => new()
{
Localization = EncounterDisplayLocalization.Get(language),
Strings = GameInfo.GetStrings(language),
};
public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, GameStrings strings, bool verbose = false)
public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, bool verbose = false, string language = GameLanguage.DefaultLanguage) => GetTextLines(enc, GetContext(language), verbose);
public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, EncounterDisplayContext ctx, bool verbose = false)
{
var lines = new List<string>();
var str = strings.Species;
var name = (uint)enc.Species < str.Count ? str[enc.Species] : enc.Species.ToString();
var EncounterName = $"{(enc is IEncounterable ie ? ie.LongName : "Special")} ({name})";
lines.Add(string.Format(L_FEncounterType_0, EncounterName));
var loc = ctx.Localization;
var name = ctx.GetSpeciesName(enc);
lines.Add(string.Format(loc.Format, loc.EncounterType, name));
if (enc is MysteryGift mg)
{
lines.AddRange(mg.GetDescription());
@ -26,21 +31,15 @@ public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, GameSt
{
var moves = m.Moves;
if (moves.HasMoves)
{
string result = moves.GetMovesetLine(strings.movelist);
lines.Add(result);
}
lines.Add(ctx.GetMoveset(moves));
}
var loc = enc.GetEncounterLocation(enc.Generation, enc.Version);
if (!string.IsNullOrEmpty(loc))
lines.Add(string.Format(L_F0_1, "Location", loc));
var location = enc.GetEncounterLocation(enc.Generation, enc.Version);
if (!string.IsNullOrEmpty(location))
lines.Add(string.Format(loc.Format, loc.Location, location));
var game = enc.Version.IsValidSavedVersion() ? strings.gamelist[(int)enc.Version] : enc.Version.ToString();
lines.Add(string.Format(L_F0_1, nameof(GameVersion), game));
lines.Add(enc.LevelMin == enc.LevelMax
? $"Level: {enc.LevelMin}"
: $"Level: {enc.LevelMin}-{enc.LevelMax}");
lines.Add(ctx.GetVersionDisplay(enc));
lines.Add(ctx.GetLevelDisplay(enc));
if (!verbose)
return lines;
@ -56,3 +55,37 @@ public static IReadOnlyList<string> GetTextLines(this IEncounterInfo enc, GameSt
return lines;
}
}
public record struct EncounterDisplayContext
{
public required EncounterDisplayLocalization Localization { get; init; }
public required GameStrings Strings { get; init; }
public string GetSpeciesName(IEncounterTemplate enc)
{
var encSpecies = enc.Species;
var str = Strings.Species;
var name = (uint)encSpecies < str.Count ? str[encSpecies] : encSpecies.ToString();
var EncounterName = $"{(enc is IEncounterable ie ? ie.LongName : "Special")} ({name})";
return EncounterName;
}
public string GetMoveset(Moveset moves) => moves.GetMovesetLine(Strings.movelist);
public string GetVersionDisplay(IEncounterTemplate enc)
{
var version = enc.Version;
var versionName = enc.Version.IsValidSavedVersion()
? Strings.gamelist[(int)enc.Version]
: enc.Version.ToString();
return string.Format(Localization.Format, Localization.Version, versionName);
}
public string GetLevelDisplay(IEncounterTemplate enc)
{
if (enc.LevelMin == enc.LevelMax)
return string.Format(Localization.Format, Localization.Level, enc.LevelMin);
return string.Format(Localization.Format, Localization.LevelRange, enc.LevelMin, enc.LevelMax);
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -21,15 +21,15 @@ public static class EncounterVerifier
private static CheckResult VerifyEncounter(PKM pk, IEncounterTemplate enc) => enc switch
{
EncounterShadow3Colo { IsEReader: true } when pk.Language != (int)LanguageID.Japanese => GetInvalid(LG3EReader),
EncounterStatic3 { Species: (int)Species.Mew } when pk.Language != (int)LanguageID.Japanese => GetInvalid(LEncUnreleasedEMewJP),
EncounterStatic3 { Species: (int)Species.Deoxys, Location: 200 } when pk.Language == (int)LanguageID.Japanese => GetInvalid(LEncUnreleased),
EncounterStatic4 { IsRoaming: true } when pk is G4PKM { MetLocation: 193, GroundTile: GroundTileType.Water } => GetInvalid(LG4InvalidTileR45Surf),
EncounterShadow3Colo { IsEReader: true } when pk.Language != (int)LanguageID.Japanese => GetInvalid(G3EReader),
EncounterStatic3 { Species: (int)Species.Mew } when pk.Language != (int)LanguageID.Japanese => GetInvalid(EncUnreleasedEMewJP),
EncounterStatic3 { Species: (int)Species.Deoxys, Location: 200 } when pk.Language == (int)LanguageID.Japanese => GetInvalid(EncUnreleased),
EncounterStatic4 { IsRoaming: true } when pk is G4PKM { MetLocation: 193, GroundTile: GroundTileType.Water } => GetInvalid(G4InvalidTileR45Surf),
MysteryGift g => VerifyEncounterEvent(pk, g),
IEncounterEgg e when pk.IsEgg => VerifyEncounterEggUnhatched(pk, e),
{ IsEgg: true } when !pk.IsEgg => VerifyEncounterEggHatched(pk, enc.Context),
EncounterInvalid => GetInvalid(LEncInvalid),
_ => GetValid(string.Empty), // todo: refactor
EncounterInvalid => GetInvalid(EncInvalid),
_ => GetValid(Valid),
};
private static CheckResult VerifyEncounterG12(PKM pk, IEncounterTemplate enc)
@ -39,11 +39,11 @@ private static CheckResult VerifyEncounterG12(PKM pk, IEncounterTemplate enc)
return enc switch
{
EncounterSlot1 => GetValid(LEncCondition),
EncounterSlot1 => GetValid(EncCondition),
EncounterSlot2 s2 => VerifyWildEncounterGen2(pk, s2),
EncounterTrade1 t => VerifyEncounterTrade(pk, t),
EncounterTrade2 => GetValid(LEncTradeMatch),
_ => GetValid(string.Empty), // todo: refactor
EncounterTrade2 => GetValid(EncTradeMatch),
_ => GetValid(Valid),
};
}
@ -51,9 +51,9 @@ private static CheckResult VerifyEncounterG12(PKM pk, IEncounterTemplate enc)
private static CheckResult VerifyWildEncounterGen2(ITrainerID16 pk, EncounterSlot2 enc) => enc.Type switch
{
SlotType2.Headbutt or SlotType2.HeadbuttSpecial => enc.IsTreeAvailable(pk.TID16)
? GetValid(LG2TreeID)
: GetInvalid(LG2InvalidTileTreeNotFound),
_ => GetValid(LEncCondition),
? GetValid(G2TreeID)
: GetInvalid(G2InvalidTileTreeNotFound),
_ => GetValid(EncCondition),
};
// Eggs
@ -68,7 +68,7 @@ private static CheckResult VerifyEncounterG12(PKM pk, IEncounterTemplate enc)
EncounterEgg8b=> VerifyUnhatchedEgg(pk, Locations.LinkTrade6NPC, Locations.Default8bNone),
EncounterEgg8 => VerifyUnhatchedEgg(pk, Locations.LinkTrade6),
EncounterEgg9 => VerifyUnhatchedEgg(pk, Locations.LinkTrade6),
_ => GetInvalid(LEggLocationInvalid),
_ => GetInvalid(EggLocationInvalid),
};
private static CheckResult VerifyEncounterEggHatched(PKM pk, EntityContext context) => context switch
@ -82,46 +82,46 @@ private static CheckResult VerifyEncounterG12(PKM pk, IEncounterTemplate enc)
EntityContext.Gen8b=> VerifyEncounterEgg8BDSP(pk),
EntityContext.Gen8 => VerifyEncounterEgg8(pk),
EntityContext.Gen9 => VerifyEncounterEgg9(pk),
_ => GetInvalid(LEggLocationInvalid),
_ => GetInvalid(EggLocationInvalid),
};
private static CheckResult VerifyEncounterEgg2(PKM pk)
{
if (pk is not ICaughtData2 { CaughtData: not 0 } c2)
return GetValid(LEggLocation);
return GetValid(EggLocation);
if (c2.MetLevel != EggStateLegality.EggMetLevel)
return GetInvalid(string.Format(LEggFMetLevel_0, EggStateLegality.EggMetLevel));
return GetInvalid(EggFMetLevel_0, EggStateLegality.EggMetLevel);
if (pk.MetLocation > 95)
return GetInvalid(LEggMetLocationFail);
return GetInvalid(EggMetLocationFail);
// Any met location is fine.
return GetValid(LEggLocation);
return GetValid(EggLocation);
}
private static CheckResult VerifyUnhatchedEgg2(PKM pk)
{
if (pk is not ICaughtData2 { CaughtData: not 0 } c2)
return new CheckResult(CheckIdentifier.Encounter);
return CheckResult.GetValid(CheckIdentifier.Encounter);
if (c2.MetLevel != EggStateLegality.EggMetLevel)
return GetInvalid(string.Format(LEggFMetLevel_0, EggStateLegality.EggMetLevel));
return GetInvalid(EggFMetLevel_0, EggStateLegality.EggMetLevel);
if (c2.MetLocation != 0)
return GetInvalid(LEggLocationInvalid);
return GetValid(LEggLocation);
return GetInvalid(EggLocationInvalid);
return GetValid(EggLocation);
}
private static CheckResult VerifyUnhatchedEgg3(PKM pk)
{
if (pk.MetLevel != EggStateLegality.EggMetLevel34)
return GetInvalid(string.Format(LEggFMetLevel_0, EggStateLegality.EggMetLevel34));
return GetInvalid(EggFMetLevel_0, EggStateLegality.EggMetLevel34);
// Only EncounterEgg should reach here.
var loc = pk.FRLG ? Locations.HatchLocationFRLG : Locations.HatchLocationRSE;
if (pk.MetLocation != loc)
return GetInvalid(LEggMetLocationFail);
return GetInvalid(EggMetLocationFail);
return GetValid(LEggLocation);
return GetValid(EggLocation);
}
private static CheckResult VerifyEncounterEgg3(PKM pk)
@ -130,46 +130,47 @@ private static CheckResult VerifyEncounterEgg3(PKM pk)
return VerifyEncounterEgg3Transfer(pk);
if (pk.MetLevel != EggStateLegality.EggMetLevel34)
return GetInvalid(string.Format(LEggFMetLevel_0, EggStateLegality.EggMetLevel34));
return GetInvalid(EggFMetLevel_0, EggStateLegality.EggMetLevel34);
// Check the origin game list.
var met = (byte)pk.MetLocation;
bool valid = EggHatchLocation3.IsValidMet3(met, pk.Version);
if (valid)
return GetValid(LEggLocation);
return GetValid(EggLocation);
// Version isn't updated when hatching on a different game. Check any game.
if (EggHatchLocation3.IsValidMet3Any(met))
return GetValid(LEggLocationTrade);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocationTrade);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult GetInvalid(string message, CheckIdentifier ident = CheckIdentifier.Encounter) => new(Severity.Invalid, ident, message);
private static CheckResult GetValid(string message) => new(Severity.Valid, CheckIdentifier.Encounter, message);
private static CheckResult GetInvalid(LegalityCheckResultCode message, CheckIdentifier ident = CheckIdentifier.Encounter) => CheckResult.Get(Severity.Invalid, ident, message);
private static CheckResult GetInvalid(LegalityCheckResultCode message, byte value, CheckIdentifier ident = CheckIdentifier.Encounter) => CheckResult.Get(Severity.Invalid, ident, message, value);
private static CheckResult GetValid(LegalityCheckResultCode message) => CheckResult.Get(Severity.Valid, CheckIdentifier.Encounter, message);
private static CheckResult VerifyEncounterEgg3Transfer(PKM pk)
{
if (pk.IsEgg)
return GetInvalid(LTransferEgg);
return GetInvalid(TransferEgg);
if (pk.MetLevel < EggStateLegality.EggLevel23)
return GetInvalid(LTransferEggMetLevel);
return GetInvalid(TransferEggMetLevel);
var expectEgg = pk is PB8 ? Locations.Default8bNone : 0;
if (pk.EggLocation != expectEgg)
return GetInvalid(LEggLocationNone);
return GetInvalid(EggLocationNone);
if (pk.Format != 4)
{
if (pk.MetLocation != Locations.Transfer4)
return GetInvalid(LTransferEggLocationTransporter);
return GetInvalid(TransferEggLocationTransporter);
}
else
{
if (pk.MetLocation != Locations.Transfer3)
return GetInvalid(LEggLocationPalPark);
return GetInvalid(EggLocationPalPark);
}
return GetValid(LEggLocation);
return GetValid(EggLocation);
}
private static CheckResult VerifyEncounterEgg4(PKM pk)
@ -177,49 +178,49 @@ private static CheckResult VerifyEncounterEgg4(PKM pk)
if (pk.Format != 4) // transferred
{
if (pk.IsEgg)
return GetInvalid(LTransferEgg);
return GetInvalid(TransferEgg);
if (pk.MetLevel < EggStateLegality.EggLevel)
return GetInvalid(LTransferEggMetLevel);
return GetInvalid(TransferEggMetLevel);
if (pk.MetLocation != Locations.Transfer4)
return GetInvalid(LTransferEggLocationTransporter);
return GetValid(LEggLocation);
return GetInvalid(TransferEggLocationTransporter);
return GetValid(EggLocation);
}
// Native
const byte level = EggStateLegality.EggMetLevel34;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = EggHatchLocation4.IsValidMet4(met, pk.Version);
if (valid)
return GetValid(LEggLocation);
return GetValid(EggLocation);
// Version isn't updated when hatching on a different game. Check any game.
if (pk.EggLocation == Locations.LinkTrade4 && EggHatchLocation4.IsValidMet4Any(met))
return GetValid(LEggLocationTrade);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocationTrade);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyEncounterEgg5(PKM pk)
{
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = EggHatchLocation5.IsValidMet5(met, pk.Version);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyEncounterEgg6(PKM pk)
{
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = pk.XY
@ -227,15 +228,15 @@ private static CheckResult VerifyEncounterEgg6(PKM pk)
: EggHatchLocation6.IsValidMet6AO(met);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyEncounterEgg7(PKM pk)
{
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = pk.SM
@ -243,20 +244,20 @@ private static CheckResult VerifyEncounterEgg7(PKM pk)
: EggHatchLocation7.IsValidMet7USUM(met);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyEncounterEgg8(PKM pk)
{
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var valid = IsValidMetForeignEggSWSH(pk, pk.MetLocation);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static bool IsValidMetForeignEggSWSH(PKM pk, ushort met)
@ -275,7 +276,7 @@ private static CheckResult VerifyEncounterEgg8BDSP(PKM pk)
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = pk.Version == GameVersion.BD
@ -283,8 +284,8 @@ private static CheckResult VerifyEncounterEgg8BDSP(PKM pk)
: EggHatchLocation8b.IsValidMet8SP(met);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyEncounterEgg9(PKM pk)
@ -294,7 +295,7 @@ private static CheckResult VerifyEncounterEgg9(PKM pk)
const byte level = EggStateLegality.EggMetLevel;
if (pk.MetLevel != level)
return GetInvalid(string.Format(LEggFMetLevel_0, level));
return GetInvalid(EggFMetLevel_0, level);
var met = pk.MetLocation;
bool valid = pk.Version == GameVersion.SL
@ -302,40 +303,40 @@ private static CheckResult VerifyEncounterEgg9(PKM pk)
: EggHatchLocation9.IsValidMet9VL(met);
if (valid)
return GetValid(LEggLocation);
return GetInvalid(LEggLocationInvalid);
return GetValid(EggLocation);
return GetInvalid(EggLocationInvalid);
}
private static CheckResult VerifyUnhatchedEgg(PKM pk, int tradeLoc, ushort noneLoc = 0)
{
var eggLevel = pk.Format is 3 or 4 ? EggStateLegality.EggMetLevel34 : EggStateLegality.EggMetLevel;
if (pk.MetLevel != eggLevel)
return GetInvalid(string.Format(LEggFMetLevel_0, eggLevel));
return GetInvalid(EggFMetLevel_0, eggLevel);
if (pk.EggLocation == tradeLoc)
return GetInvalid(LEggLocationTradeFail);
return GetInvalid(EggLocationTradeFail);
var met = pk.MetLocation;
if (met == tradeLoc)
return GetValid(LEggLocationTrade);
return GetValid(EggLocationTrade);
return met == noneLoc
? GetValid(LEggUnhatched)
: GetInvalid(LEggLocationNone);
? GetValid(EggUnhatched)
: GetInvalid(EggLocationNone);
}
private static CheckResult VerifyUnhatchedEgg5(PKM pk)
{
const byte eggLevel = EggStateLegality.EggMetLevel;
if (pk.MetLevel != eggLevel)
return GetInvalid(string.Format(LEggFMetLevel_0, eggLevel));
return GetInvalid(EggFMetLevel_0, eggLevel);
if (pk.EggLocation is (Locations.LinkTrade5 or Locations.LinkTrade5NPC))
return GetInvalid(LEggLocationTradeFail);
return GetInvalid(EggLocationTradeFail);
var met = pk.MetLocation;
if (met is (Locations.LinkTrade5 or Locations.LinkTrade5NPC))
return GetValid(LEggLocationTrade);
return GetValid(EggLocationTrade);
return met == 0
? GetValid(LEggUnhatched)
: GetInvalid(LEggLocationNone);
? GetValid(EggUnhatched)
: GetInvalid(EggLocationNone);
}
private static CheckResult VerifyEncounterTrade(ISpeciesForm pk, EncounterTrade1 trade)
@ -346,23 +347,13 @@ private static CheckResult VerifyEncounterTrade(ISpeciesForm pk, EncounterTrade1
// Pokémon that evolve on trade can not be in the phase evolution after the trade
// If the trade holds an Everstone, EvolveOnTrade will be false for the encounter
// No need to range check the species, as it matched to a valid encounter species.
var names = ParseSettings.SpeciesStrings;
var evolved = names[species + 1];
var unevolved = names[species];
return GetInvalid(string.Format(LEvoTradeReq, unevolved, evolved));
return GetInvalid(EncTradeShouldHaveEvolvedToSpecies_0);
}
return GetValid(LEncTradeMatch);
return GetValid(EncTradeMatch);
}
private static CheckResult VerifyEncounterEvent(PKM pk, MysteryGift gift)
{
switch (gift)
{
case PCD pcd:
if (!pcd.CanBeReceivedByVersion(pk.Version) && pcd.Gift.PK.Version == 0)
return GetInvalid(string.Format(L_XMatches0_1, gift.CardHeader, $"-- {LEncGiftVersionNotDistributed}"));
break;
}
if (!pk.IsEgg && gift.IsEgg) // hatched
{
var hatchCheck = VerifyEncounterEggHatched(pk, gift.Context);
@ -371,6 +362,6 @@ private static CheckResult VerifyEncounterEvent(PKM pk, MysteryGift gift)
}
// Strict matching already performed by EncounterGenerator. May be worth moving some checks here to better flag invalid gifts.
return GetValid(string.Format(L_XMatches0_1, gift.CardHeader, string.Empty));
return GetValid(Valid);
}
}

View File

@ -1,5 +1,5 @@
using static PKHeX.Core.EvolutionRestrictions;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -8,7 +8,7 @@ namespace PKHeX.Core;
/// </summary>
public static class EvolutionVerifier
{
private static readonly CheckResult VALID = new(CheckIdentifier.Evolution);
private static readonly CheckResult VALID = CheckResult.GetValid(CheckIdentifier.Evolution);
/// <summary>
/// Verifies Evolution scenarios of <see cref="IEncounterable"/> templates for an input <see cref="PKM"/> and relevant <see cref="LegalInfo"/>.
@ -19,11 +19,11 @@ public static CheckResult VerifyEvolution(PKM pk, LegalInfo info)
{
// Check if basic evolution methods are satisfiable with this encounter.
if (!IsValidEvolution(pk, info.EvoChainsAllGens, info.EncounterOriginal))
return new CheckResult(Severity.Invalid, CheckIdentifier.Evolution, LEvoInvalid);
return CheckResult.Get(Severity.Invalid, CheckIdentifier.Evolution, EvoInvalid);
// Check if complex evolution methods are satisfiable with this encounter.
if (!IsValidEvolutionWithMove(pk, info))
return new CheckResult(Severity.Invalid, CheckIdentifier.Evolution, string.Format(LMoveEvoFCombination_0, ParseSettings.SpeciesStrings[pk.Species]));
return CheckResult.Get(Severity.Invalid, CheckIdentifier.Evolution, MoveEvoFCombination_0, pk.Species);
return VALID;
}

View File

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
@ -38,24 +38,24 @@ public static CheckResult VerifyGift(PKM pk, MysteryGift g)
{
bool restricted = TryGetRestriction(g, out var value);
if (!restricted)
return new CheckResult(CheckIdentifier.GameOrigin);
return CheckResult.GetValid(CheckIdentifier.GameOrigin);
var version = (int)value >> 16;
if (version != 0 && !CanVersionReceiveGift(g.Generation, version, pk.Version))
return new CheckResult(Severity.Invalid, CheckIdentifier.GameOrigin, LEncGiftVersionNotDistributed);
return CheckResult.Get(Severity.Invalid, CheckIdentifier.GameOrigin, EncGiftVersionNotDistributed);
var lang = value & MysteryGiftRestriction.LangRestrict;
if (lang != 0 && !lang.HasFlag((MysteryGiftRestriction) (1 << pk.Language)))
return new CheckResult(Severity.Invalid, CheckIdentifier.GameOrigin, string.Format(LOTLanguage, lang.GetSuggestedLanguage(), pk.Language));
return CheckResult.Get(Severity.Invalid, CheckIdentifier.GameOrigin, OTLanguageShouldBe_0, (ushort)lang.GetSuggestedLanguage());
if (pk is IRegionOriginReadOnly tr)
{
var region = value & MysteryGiftRestriction.RegionRestrict;
if (region != 0 && !region.HasFlag((MysteryGiftRestriction)((int)MysteryGiftRestriction.RegionBase << tr.ConsoleRegion)))
return new CheckResult(Severity.Invalid, CheckIdentifier.GameOrigin, LGeoHardwareRange);
return CheckResult.Get(Severity.Invalid, CheckIdentifier.GameOrigin, EncGiftRegionNotDistributed, (ushort)region.GetSuggestedRegion());
}
return new CheckResult(CheckIdentifier.GameOrigin);
return CheckResult.GetValid(CheckIdentifier.GameOrigin);
}
private static bool TryGetRestriction(MysteryGift g, out MysteryGiftRestriction val)

View File

@ -82,10 +82,10 @@ public EvolutionCheckResult Check(PKM pk, byte lvl, byte levelMin, bool skipChec
// Version checks come in pairs, check for any pair match
LevelUpVersion or LevelUpVersionDay or LevelUpVersionNight when (((byte)pk.Version & 1) != (Argument & 1) && pk.IsUntraded) => skipChecks ? Valid : VisitVersion,
LevelUpKnowMoveEC100 when pk.EncryptionConstant % 100 != 0 => skipChecks ? Valid : WrongEC,
LevelUpKnowMoveECElse when pk.EncryptionConstant % 100 == 0 => skipChecks ? Valid : WrongEC,
LevelUpInBattleEC100 when pk.EncryptionConstant % 100 != 0 => skipChecks ? Valid : WrongEC,
LevelUpInBattleECElse when pk.EncryptionConstant % 100 == 0 => skipChecks ? Valid : WrongEC,
LevelUpKnowMoveEC100 when !EvolutionRestrictions.IsEvolvedSpeciesFormRare(pk.EncryptionConstant) => skipChecks ? Valid : WrongEC,
LevelUpKnowMoveECElse when EvolutionRestrictions.IsEvolvedSpeciesFormRare(pk.EncryptionConstant) => skipChecks ? Valid : WrongEC,
LevelUpInBattleEC100 when !EvolutionRestrictions.IsEvolvedSpeciesFormRare(pk.EncryptionConstant) => skipChecks ? Valid : WrongEC,
LevelUpInBattleECElse when EvolutionRestrictions.IsEvolvedSpeciesFormRare(pk.EncryptionConstant) => skipChecks ? Valid : WrongEC,
_ => Valid,
};

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
@ -12,49 +11,52 @@ public sealed class BaseLegalityFormatter : ILegalityFormatter
/// <summary>
/// Gets a minimal report string for the analysis.
/// </summary>
public string GetReport(LegalityAnalysis l)
public string GetReport(in LegalityLocalizationContext la)
{
var l = la.Analysis;
if (l.Valid)
return L_ALegal;
return la.Settings.Lines.Legal;
if (!l.Parsed)
return L_AnalysisUnavailable;
return la.Settings.Lines.AnalysisUnavailable;
List<string> lines = [];
GetLegalityReportLines(l, lines);
GetLegalityReportLines(la, lines);
return string.Join(Environment.NewLine, lines);
}
/// <summary>
/// Gets a verbose report string for the analysis.
/// </summary>
public string GetReportVerbose(LegalityAnalysis l)
public string GetReportVerbose(in LegalityLocalizationContext la)
{
var l = la.Analysis;
if (!l.Parsed)
return L_AnalysisUnavailable;
return la.Settings.Lines.AnalysisUnavailable;
var lines = GetVerboseLegalityReportLines(l);
var lines = GetVerboseLegalityReportLines(la);
return string.Join(Environment.NewLine, lines);
}
private static void GetLegalityReportLines(LegalityAnalysis l, List<string> lines)
private static void GetLegalityReportLines(in LegalityLocalizationContext la, List<string> lines)
{
var l = la.Analysis;
var info = l.Info;
var pk = l.Entity;
var evos = info.EvoChainsAllGens;
LegalityFormatting.AddMoves(info.Moves, lines, pk.Format, false, pk, evos);
LegalityFormatting.AddMoves(la, info.Moves, lines, pk.Format, false);
if (pk.Format >= 6)
LegalityFormatting.AddRelearn(info.Relearn, lines, false, pk, evos);
LegalityFormatting.AddSecondaryChecksInvalid(l.Results, lines);
LegalityFormatting.AddRelearn(la, info.Relearn, lines, false);
LegalityFormatting.AddSecondaryChecksInvalid(la, l.Results, lines);
}
private static List<string> GetVerboseLegalityReportLines(LegalityAnalysis l)
private static List<string> GetVerboseLegalityReportLines(in LegalityLocalizationContext la)
{
var l = la.Analysis;
var lines = new List<string>();
if (l.Valid)
lines.Add(L_ALegal);
lines.Add(la.Settings.Lines.Legal);
else
GetLegalityReportLines(l, lines);
GetLegalityReportLines(la, lines);
var info = l.Info;
var pk = l.Entity;
const string separator = "===";
@ -63,20 +65,19 @@ private static List<string> GetVerboseLegalityReportLines(LegalityAnalysis l)
int initialCount = lines.Count;
var format = pk.Format;
var evos = info.EvoChainsAllGens;
LegalityFormatting.AddMoves(info.Moves, lines, format, true, pk, evos);
LegalityFormatting.AddMoves(la, info.Moves, lines, format, true);
if (format >= 6)
LegalityFormatting.AddRelearn(info.Relearn, lines, true, pk, evos);
LegalityFormatting.AddRelearn(la, info.Relearn, lines, true);
if (lines.Count != initialCount) // move info added, break for next section
lines.Add(string.Empty);
LegalityFormatting.AddSecondaryChecksValid(l.Results, lines);
LegalityFormatting.AddSecondaryChecksValid(la, l.Results, lines);
lines.Add(separator);
lines.Add(string.Empty);
LegalityFormatting.AddEncounterInfo(l, lines);
LegalityFormatting.AddEncounterInfo(la, lines);
return lines;
}

View File

@ -1,4 +1,4 @@
namespace PKHeX.Core;
namespace PKHeX.Core;
/// <summary>
/// Formats legality results into a <see cref="T:System.String"/> for display.
@ -8,10 +8,10 @@ public interface ILegalityFormatter
/// <summary>
/// Gets a small summary of the legality analysis.
/// </summary>
string GetReport(LegalityAnalysis l);
string GetReport(in LegalityLocalizationContext l);
/// <summary>
/// Gets a verbose summary of the legality analysis.
/// </summary>
string GetReportVerbose(LegalityAnalysis l);
string GetReportVerbose(in LegalityLocalizationContext l);
}

View File

@ -1,523 +0,0 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Diagnostics.CodeAnalysis;
namespace PKHeX.Core;
/// <summary>
/// Legality Check Message Strings to indicate why certain <see cref="PKM"/> <see cref="LegalInfo"/> values are flagged.
/// </summary>
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public static class LegalityCheckStrings
{
// Message String Name format: L/F[Category][Summary]
#region General Strings
/// <summary>Default text for indicating validity.</summary>
public static string L_AValid { get; set; } = "Valid.";
/// <summary>Default text for indicating legality.</summary>
public static string L_ALegal { get; set; } = "Legal!";
/// <summary>Default text for indicating an error has occurred.</summary>
public static string L_AError { get; set; } = "Internal error.";
/// <summary>Analysis not available for the <see cref="PKM"/></summary>
public static string L_AnalysisUnavailable { get; set; } = "Analysis not available for this Pokémon.";
/// <summary>Format text for exporting a legality check result.</summary>
public static string L_F0_1 { get; set; } = "{0}: {1}";
/// <summary>Format text for exporting a legality check result for a Move.</summary>
public static string L_F0_M_1_2 { get; set; } = "{0} Move {1}: {2}";
/// <summary>Format text for exporting a legality check result for a Relearn Move.</summary>
public static string L_F0_RM_1_2 { get; set; } = "{0} Relearn Move {1}: {2}";
/// <summary>Format text for exporting the type of Encounter that was matched for the <see cref="PKM"/></summary>
public static string L_FEncounterType_0 { get; set; } = "Encounter Type: {0}";
/// <summary>Format text for exporting the <see cref="PIDIV.OriginSeed"/> that was matched for the <see cref="PKM"/></summary>
public static string L_FOriginSeed_0 { get; set; } = "Origin Seed: {0}";
/// <summary>Format text for exporting the <see cref="PIDIV.Type"/> that was matched for the <see cref="PKM"/></summary>
public static string L_FPIDType_0 { get; set; } = "PID Type: {0}";
/// <summary>Severity string for <see cref="Severity.Invalid"/></summary>
public static string L_SInvalid { get; set; } = "Invalid";
/// <summary>Severity string for <see cref="Severity.Fishy"/></summary>
public static string L_SFishy { get; set; } = "Fishy";
/// <summary>Severity string for <see cref="Severity.Valid"/></summary>
public static string L_SValid { get; set; } = "Valid";
/// <summary>Severity string for anything not implemented.</summary>
public static string L_SNotImplemented { get; set; } = "Not Implemented";
public static string L_XOT { get; set; } = "OT";
public static string L_XHT { get; set; } = "HT";
public static string L_XNickname { get; set; } = "Nickname";
public static string L_XKorean { get; set; } = "Korean";
public static string L_XKoreanNon { get; set; } = "Non-Korean";
public static string L_XLocation { get; set; } = "Location";
public static string L_XEnigmaBerry_0 { get; set; } = "{0} Berry";
public static string L_XMatches0_1 { get; set; } = "Matches: {0} {1}";
public static string L_XWurmpleEvo_0 { get; set; } = "Wurmple Evolution: {0}";
public static string L_XRareFormEvo_0_1 { get; set; } = "Evolves into form: {0} (rare: {1})";
public static string LAbilityCapsuleUsed { get; set; } = "Ability available with Ability Capsule.";
public static string LAbilityPatchUsed { get; set; } = "Ability available with Ability Patch.";
public static string LAbilityPatchRevertUsed { get; set; } = "Ability available with Ability Patch Revert.";
public static string LAbilityFlag { get; set; } = "Ability matches ability number.";
public static string LAbilityHiddenFail { get; set; } = "Hidden Ability mismatch for encounter type.";
public static string LAbilityHiddenUnavailable { get; set; } = "Hidden Ability not available.";
public static string LAbilityMismatch { get; set; } = "Ability mismatch for encounter.";
public static string LAbilityMismatch3 { get; set; } = "Ability does not match Generation 3 species ability.";
public static string LAbilityMismatchFlag { get; set; } = "Ability does not match ability number.";
public static string LAbilityMismatchGift { get; set; } = "Ability does not match Mystery Gift.";
public static string LAbilityMismatchGrotto { get; set; } = "Hidden Grotto captures should have Hidden Ability.";
public static string LAbilityMismatchHordeSafari { get; set; } = "Hidden Ability on non-horde/friend safari wild encounter.";
public static string LAbilityMismatchPID { get; set; } = "Ability does not match PID.";
public static string LAbilityMismatchSOS { get; set; } = "Hidden Ability on non-SOS wild encounter.";
public static string LAbilityUnexpected { get; set; } = "Ability is not valid for species/form.";
public static string LAwakenedCap { get; set; } = "Individual AV cannot be greater than {0}.";
public static string LAwakenedShouldBeValue { get; set; } = "Individual AV ({1}) should be greater than {0}.";
public static string LBallAbility { get; set; } = "Can't obtain Hidden Ability with Ball.";
public static string LBallEggCherish { get; set; } = "Can't have Cherish Ball for regular Egg.";
public static string LBallEggMaster { get; set; } = "Can't have Master Ball for regular Egg.";
public static string LBallEnc { get; set; } = "Correct ball for encounter type.";
public static string LBallEncMismatch { get; set; } = "Can't have ball for encounter type.";
public static string LBallHeavy { get; set; } = "Can't have Heavy Ball for light, low-catch rate species (Gen VII).";
public static string LBallNone { get; set; } = "No check satisfied, assuming illegal.";
public static string LBallSpecies { get; set; } = "Can't obtain species in Ball.";
public static string LBallSpeciesPass { get; set; } = "Ball possible for species.";
public static string LBallUnavailable { get; set; } = "Ball unobtainable in origin Generation.";
public static string LContestZero { get; set; } = "Contest Stats should be 0.";
public static string LContestZeroSheen { get; set; } = "Contest Stat Sheen should be 0.";
public static string LContestSheenTooLow_0 { get; set; } = "Contest Stat Sheen should be >= {0}.";
public static string LContestSheenTooHigh_0 { get; set; } = "Contest Stat Sheen should be <= {0}.";
public static string LDateOutsideConsoleWindow { get; set; } = "Local Date is outside of console's local time window.";
public static string LDateTimeClockInvalid { get; set; } = "Local Time is not a valid timestamp.";
public static string LDateOutsideDistributionWindow { get; set; } = "Met Date is outside of distribution window.";
public static string LEggContest { get; set; } = "Cannot increase Contest Stats of an Egg.";
public static string LEggEXP { get; set; } = "Eggs cannot receive experience.";
public static string LEggFMetLevel_0 { get; set; } = "Invalid Met Level, expected {0}.";
public static string LEggHatchCycles { get; set; } = "Invalid Egg hatch cycles.";
public static string LEggLocation { get; set; } = "Able to hatch an Egg at Met Location.";
public static string LEggLocationInvalid { get; set; } = "Can't hatch an Egg at Met Location.";
public static string LEggLocationNone { get; set; } = "Invalid Egg Location, expected none.";
public static string LEggLocationPalPark { get; set; } = "Invalid Met Location, expected Pal Park.";
public static string LEggLocationTrade { get; set; } = "Able to hatch a traded Egg at Met Location.";
public static string LEggLocationTradeFail { get; set; } = "Invalid Egg Location, shouldn't be 'traded' while an Egg.";
public static string LEggMetLocationFail { get; set; } = "Can't obtain Egg from Egg Location.";
public static string LEggNature { get; set; } = "Eggs cannot have their Stat Nature changed.";
public static string LEggPokeathlon { get; set; } = "Eggs cannot have Pokéathlon stats.";
public static string LEggPokerus { get; set; } = "Eggs cannot be infected with Pokérus.";
public static string LEggPP { get; set; } = "Eggs cannot have modified move PP counts.";
public static string LEggPPUp { get; set; } = "Cannot apply PP Ups to an Egg.";
public static string LEggRelearnFlags { get; set; } = "Expected no Relearn Move Flags.";
public static string LEggShinyLeaf { get; set; } = "Eggs cannot have Shiny Leaf/Crown.";
public static string LEggShinyPokeStar { get; set; } = "Eggs cannot be a Pokéstar Studios star.";
public static string LEggSpecies { get; set; } = "Can't obtain Egg for this species.";
public static string LEggUnhatched { get; set; } = "Valid un-hatched Egg.";
public static string LEncCondition { get; set; } = "Valid Wild Encounter at location.";
public static string LEncConditionBadRNGFrame { get; set; } = "Unable to match encounter conditions to a possible RNG frame.";
public static string LEncConditionBadSpecies { get; set; } = "Species does not exist in origin game.";
public static string LEncConditionBlack { get; set; } = "Valid Wild Encounter at location (Black Flute).";
public static string LEncConditionBlackLead { get; set; } = "Valid Wild Encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).";
public static string LEncConditionDexNav { get; set; } = "Valid Wild Encounter at location (DexNav).";
public static string LEncConditionLead { get; set; } = "Valid Wild Encounter at location (Pressure/Hustle/Vital Spirit).";
public static string LEncConditionWhite { get; set; } = "Valid Wild Encounter at location (White Flute).";
public static string LEncConditionWhiteLead { get; set; } = "Valid Wild Encounter at location (White Flute & Pressure/Hustle/Vital Spirit).";
public static string LEncGift { get; set; } = "Unable to match a gift Egg encounter from origin game.";
public static string LEncGiftEggEvent { get; set; } = "Unable to match an event Egg encounter from origin game.";
public static string LEncGiftIVMismatch { get; set; } = "IVs do not match Mystery Gift Data.";
public static string LEncGiftNicknamed { get; set; } = "Event gift has been nicknamed.";
public static string LEncGiftNotFound { get; set; } = "Unable to match to a Mystery Gift in the database.";
public static string LEncGiftPIDMismatch { get; set; } = "Mystery Gift fixed PID mismatch.";
public static string LEncGiftShinyMismatch { get; set; } = "Mystery Gift shiny mismatch.";
public static string LEncGiftVersionNotDistributed { get; set; } = "Mystery Gift cannot be received by this version.";
public static string LEncInvalid { get; set; } = "Unable to match an encounter from origin game.";
public static string LEncMasteryInitial { get; set; } = "Initial move mastery flags do not match the encounter's expected state.";
public static string LEncTradeChangedNickname { get; set; } = "In-game Trade Nickname has been altered.";
public static string LEncTradeChangedOT { get; set; } = "In-game Trade OT has been altered.";
public static string LEncTradeIndexBad { get; set; } = "In-game Trade invalid index?";
public static string LEncTradeMatch { get; set; } = "Valid In-game trade.";
public static string LEncTradeUnchanged { get; set; } = "In-game Trade OT and Nickname have not been altered.";
public static string LEncStaticMatch { get; set; } = "Valid gift/static encounter.";
public static string LEncStaticPIDShiny { get; set; } = "Static Encounter shiny mismatch.";
public static string LEncStaticRelearn { get; set; } = "Static encounter relearn move mismatch.";
public static string LEncTypeMatch { get; set; } = "Encounter Type matches encounter.";
public static string LEncTypeMismatch { get; set; } = "Encounter Type does not match encounter.";
public static string LEncUnreleased { get; set; } = "Unreleased event.";
public static string LEncUnreleasedEMewJP { get; set; } = "Non japanese Mew from Faraway Island. Unreleased event.";
public static string LEncUnreleasedHoOArceus { get; set; } = "Arceus from Hall of Origin. Unreleased event.";
public static string LEncUnreleasedPtDarkrai { get; set; } = "Non Platinum Darkrai from Newmoon Island. Unreleased event.";
public static string LEncUnreleasedPtShaymin { get; set; } = "Non Platinum Shaymin from Flower Paradise. Unreleased event.";
public static string LEReaderAmerica { get; set; } = "American E-Reader Berry in Japanese save file.";
public static string LEReaderInvalid { get; set; } = "Invalid E-Reader Berry.";
public static string LEReaderJapan { get; set; } = "Japanese E-Reader Berry in international save file.";
public static string LEffort2Remaining { get; set; } = "2 EVs remaining.";
public static string LEffortAbove252 { get; set; } = "EVs cannot go above 252.";
public static string LEffortAbove510 { get; set; } = "EV total cannot be above 510.";
public static string LEffortAllEqual { get; set; } = "EVs are all equal.";
public static string LEffortCap100 { get; set; } = "Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100.";
public static string LEffortEgg { get; set; } = "Eggs cannot receive EVs.";
public static string LEffortShouldBeZero { get; set; } = "Cannot receive EVs.";
public static string LEffortEXPIncreased { get; set; } = "All EVs are zero, but leveled above Met Level.";
public static string LEffortUntrainedCap { get; set; } = "Individual EV without changing EXP cannot be greater than {0}.";
public static string LEvoInvalid { get; set; } = "Evolution not valid (or level/trade evolution unsatisfied).";
public static string LEvoTradeReq { get; set; } = "In-game trade {0} should have evolved into {1}.";
public static string LEvoTradeReqOutsider { get; set; } = "Outsider {0} should have evolved into {1}.";
public static string LEvoTradeRequired { get; set; } = "Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.";
public static string LFateful { get; set; } = "Special In-game Fateful Encounter.";
public static string LFatefulGiftMissing { get; set; } = "Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?";
public static string LFatefulInvalid { get; set; } = "Fateful Encounter should not be checked.";
public static string LFatefulMissing { get; set; } = "Special In-game Fateful Encounter flag missing.";
public static string LFatefulMystery { get; set; } = "Mystery Gift Fateful Encounter.";
public static string LFatefulMysteryMissing { get; set; } = "Mystery Gift Fateful Encounter flag missing.";
public static string LFavoriteMarkingUnavailable { get; set; } = "Favorite Marking is not available.";
public static string LFormArgumentHigh { get; set; } = "Form argument is too high for current form.";
public static string LFormArgumentLow { get; set; } = "Form argument is too low for current form.";
public static string LFormArgumentNotAllowed { get; set; } = "Form argument is not allowed for this encounter.";
public static string LFormArgumentValid { get; set; } = "Form argument is valid.";
public static string LFormArgumentInvalid { get; set; } = "Form argument is not valid.";
public static string LFormBattle { get; set; } = "Form cannot exist outside of a battle.";
public static string LFormEternal { get; set; } = "Valid Eternal Flower encounter.";
public static string LFormEternalInvalid { get; set; } = "Invalid Eternal Flower encounter.";
public static string LFormInvalidGame { get; set; } = "Form cannot be obtained in origin game.";
public static string LFormInvalidNature { get; set; } = "Form cannot have this nature.";
public static string LFormInvalidRange { get; set; } = "Form Count is out of range. Expected <= {0}, got {1}.";
public static string LFormItem { get; set; } = "Held item matches Form.";
public static string LFormItemInvalid { get; set; } = "Held item does not match Form.";
public static string LFormParty { get; set; } = "Form cannot exist outside of Party.";
public static string LFormPikachuCosplay { get; set; } = "Only Cosplay Pikachu can have this form.";
public static string LFormPikachuCosplayInvalid { get; set; } = "Cosplay Pikachu cannot have the default form.";
public static string LFormPikachuEventInvalid { get; set; } = "Event Pikachu cannot have the default form.";
public static string LFormInvalidExpect_0 { get; set; } = "Form is invalid, expected form index {0}.";
public static string LFormValid { get; set; } = "Form is Valid.";
public static string LFormVivillon { get; set; } = "Valid Vivillon pattern.";
public static string LFormVivillonEventPre { get; set; } = "Event Vivillon pattern on pre-evolution.";
public static string LFormVivillonInvalid { get; set; } = "Invalid Vivillon pattern.";
public static string LFormVivillonNonNative { get; set; } = "Non-native Vivillon pattern.";
public static string LG1CatchRateChain { get; set; } = "Catch rate does not match any species from Pokémon evolution chain.";
public static string LG1CatchRateEvo { get; set; } = "Catch rate match species without encounters. Expected a preevolution catch rate.";
public static string LG1CatchRateItem { get; set; } = "Catch rate does not match a valid held item from Generation 2.";
public static string LG1CatchRateMatchPrevious { get; set; } = "Catch Rate matches a species from Pokémon evolution chain.";
public static string LG1CatchRateMatchTradeback { get; set; } = "Catch rate matches a valid held item from Generation 2.";
public static string LG1CatchRateNone { get; set; } = "Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items.";
public static string LG1CharNick { get; set; } = "Nickname from Generation 1/2 uses unavailable characters.";
public static string LG1CharOT { get; set; } = "OT from Generation 1/2 uses unavailable characters.";
public static string LG1GBEncounter { get; set; } = "Can't obtain Special encounter in Virtual Console games.";
public static string LG1MoveExclusive { get; set; } = "Generation 1 exclusive move. Incompatible with Non-tradeback moves.";
public static string LG1MoveLearnSameLevel { get; set; } = "Incompatible moves. Learned at the same level in Red/Blue and Yellow.";
public static string LG1MoveTradeback { get; set; } = "Non-tradeback Egg move. Incompatible with Generation 1 exclusive moves.";
public static string LG1OTEvent { get; set; } = "Incorrect RBY event OT Name.";
public static string LG1OTGender { get; set; } = "Female OT from Generation 1/2 is invalid.";
public static string LG1Stadium { get; set; } = "Incorrect Stadium OT.";
public static string LG1StadiumInternational { get; set; } = "Valid International Stadium OT.";
public static string LG1StadiumJapanese { get; set; } = "Valid Japanese Stadium OT.";
public static string LG1TradebackPreEvoMove { get; set; } = "Non-tradeback pre evolution move. Incompatible with Generation 1 exclusive moves.";
public static string LG1Type1Fail { get; set; } = "Invalid Type A, does not match species type.";
public static string LG1Type2Fail { get; set; } = "Invalid Type B, does not match species type.";
public static string LG1TypeMatch1 { get; set; } = "Valid Type A, matches species type.";
public static string LG1TypeMatch2 { get; set; } = "Valid Type B, matches species type.";
public static string LG1TypeMatchPorygon { get; set; } = "Porygon with valid Type A and B values.";
public static string LG1TypePorygonFail { get; set; } = "Porygon with invalid Type A and B values. Does not a match a valid type combination.";
public static string LG1TypePorygonFail1 { get; set; } = "Porygon with invalid Type A value.";
public static string LG1TypePorygonFail2 { get; set; } = "Porygon with invalid Type B value.";
public static string LG2InvalidTilePark { get; set; } = "National Park fishing encounter. Unreachable Water tiles.";
public static string LG2InvalidTileR14 { get; set; } = "Kanto Route 14 fishing encounter. Unreachable Water tiles.";
public static string LG2InvalidTileSafari { get; set; } = "Generation 2 Safari Zone fishing encounter. Unreachable zone.";
public static string LG2InvalidTileTreeID { get; set; } = "Found an unreachable tree for Crystal headbutt encounter that matches OTID.";
public static string LG2InvalidTileTreeNotFound { get; set; } = "Could not find a tree for Crystal headbutt encounter that matches OTID.";
public static string LG2TreeID { get; set; } = "Found a tree for Crystal headbutt encounter that matches OTID.";
public static string LG2OTGender { get; set; } = "OT from Virtual Console games other than Crystal cannot be female.";
public static string LG3EReader { get; set; } = "Non Japanese Shadow E-reader Pokémon. Unreleased encounter.";
public static string LG3OTGender { get; set; } = "OT from Colosseum/XD cannot be female.";
public static string LG4InvalidTileR45Surf { get; set; } = "Johto Route 45 surfing encounter. Unreachable Water tiles.";
public static string LG5ID_N { get; set; } = "The Name/TID16/SID16 of N is incorrect.";
public static string LG5IVAll30 { get; set; } = "All IVs of N's Pokémon should be 30.";
public static string LG5OTGenderN { get; set; } = "N's Pokémon must have a male OT gender.";
public static string LG5PIDShinyGrotto { get; set; } = "Hidden Grotto captures cannot be shiny.";
public static string LG5PIDShinyN { get; set; } = "N's Pokémon cannot be shiny.";
public static string LG5SparkleInvalid { get; set; } = "Special In-game N's Sparkle flag should not be checked.";
public static string LG5SparkleRequired { get; set; } = "Special In-game N's Sparkle flag missing.";
public static string LGanbaruStatTooHigh { get; set; } = "One or more Ganbaru Value is above the natural limit of (10 - IV bonus).";
public static string LGenderInvalidNone { get; set; } = "Genderless Pokémon should not have a gender.";
public static string LGeoBadOrder { get; set; } = "GeoLocation Memory: Gap/Blank present.";
public static string LGeoHardwareInvalid { get; set; } = "Geolocation: Country is not in 3DS region.";
public static string LGeoHardwareRange { get; set; } = "Invalid Console Region.";
public static string LGeoHardwareValid { get; set; } = "Geolocation: Country is in 3DS region.";
public static string LGeoMemoryMissing { get; set; } = "GeoLocation Memory: Memories should be present.";
public static string LGeoNoCountryHT { get; set; } = "GeoLocation Memory: HT Name present but has no previous Country.";
public static string LGeoNoRegion { get; set; } = "GeoLocation Memory: Region without Country.";
public static string LHyperTooLow_0 { get; set; } = "Can't Hyper Train a Pokémon that isn't level {0}.";
public static string LHyperPerfectAll { get; set; } = "Can't Hyper Train a Pokémon with perfect IVs.";
public static string LHyperPerfectOne { get; set; } = "Can't Hyper Train a perfect IV.";
public static string LHyperPerfectUnavailable { get; set; } = "Can't Hyper Train any IV(s).";
public static string LItemEgg { get; set; } = "Eggs cannot hold items.";
public static string LItemUnreleased { get; set; } = "Held item is unreleased.";
public static string LIVAllEqual_0 { get; set; } = "All IVs are {0}.";
public static string LIVNotCorrect { get; set; } = "IVs do not match encounter requirements.";
public static string LIVF_COUNT0_31 { get; set; } = "Should have at least {0} IVs = 31.";
public static string LLevelEXPThreshold { get; set; } = "Current experience matches level threshold.";
public static string LLevelEXPTooHigh { get; set; } = "Current experience exceeds maximum amount for level 100.";
public static string LLevelMetBelow { get; set; } = "Current level is below met level.";
public static string LLevelMetGift { get; set; } = "Met Level does not match Mystery Gift level.";
public static string LLevelMetGiftFail { get; set; } = "Current Level below Mystery Gift level.";
public static string LLevelMetSane { get; set; } = "Current level is not below met level.";
public static string LMarkValueOutOfRange_0 { get; set; } = "Individual marking at index {0} is not within the allowed value range.";
public static string LMarkValueShouldBeZero { get; set; } = "Marking flags cannot be set.";
public static string LMarkValueUnusedBitsPresent { get; set; } = "Marking flags uses bits beyond the accessible range.";
public static string LMemoryArgBadCatch { get; set; } = "{0} Memory: {0} did not catch this.";
public static string LMemoryArgBadHatch { get; set; } = "{0} Memory: {0} did not hatch this.";
public static string LMemoryArgBadHT { get; set; } = "Memory: Can't have Handling Trainer Memory as Egg.";
public static string LMemoryArgBadID { get; set; } = "{0} Memory: Can't obtain Memory on {0} Version.";
public static string LMemoryArgBadItem { get; set; } = "{0} Memory: Species can't hold this item.";
public static string LMemoryArgBadLocation { get; set; } = "{0} Memory: Can't obtain Location on {0} Version.";
public static string LMemoryArgBadMove { get; set; } = "{0} Memory: Species can't learn this move.";
public static string LMemoryArgBadOTEgg { get; set; } = "{0} Memory: Link Trade is not a valid first memory.";
public static string LMemoryArgBadSpecies { get; set; } = "{0} Memory: Can't capture species in game.";
public static string LMemoryArgSpecies { get; set; } = "{0} Memory: Species can be captured in game.";
public static string LMemoryCleared { get; set; } = "Memory: Not cleared properly.";
public static string LMemoryF_0_Valid { get; set; } = "{0} Memory is valid.";
public static string LMemoryFeelInvalid { get; set; } = "{0} Memory: Invalid Feeling.";
public static string LMemoryHTFlagInvalid { get; set; } = "Untraded: Current handler should not be the Handling Trainer.";
public static string LMemoryHTGender { get; set; } = "HT Gender invalid: {0}";
public static string LMemoryHTLanguage { get; set; } = "HT Language is missing.";
public static string LMemoryIndexArgHT { get; set; } = "Should have a HT Memory TextVar value (somewhere).";
public static string LMemoryIndexFeel { get; set; } = "{0} Memory: Feeling should be index {1}.";
public static string LMemoryIndexFeelHT09 { get; set; } = "Should have a HT Memory Feeling value 0-9.";
public static string LMemoryIndexID { get; set; } = "{0} Memory: Should be index {1}.";
public static string LMemoryIndexIntensity { get; set; } = "{0} Memory: Intensity should be index {1}.";
public static string LMemoryIndexIntensityHT1 { get; set; } = "Should have a HT Memory Intensity value (1st).";
public static string LMemoryIndexIntensityMin { get; set; } = "{0} Memory: Intensity should be at least {1}.";
public static string LMemoryIndexLinkHT { get; set; } = "Should have a Link Trade HT Memory.";
public static string LMemoryIndexVar { get; set; } = "{0} Memory: TextVar should be index {1}.";
public static string LMemoryMissingHT { get; set; } = "Memory: Handling Trainer Memory missing.";
public static string LMemoryMissingOT { get; set; } = "Memory: Original Trainer Memory missing.";
public static string LMemorySocialZero { get; set; } = "Social Stat should be zero.";
public static string LMemorySocialTooHigh_0 { get; set; } = "Social Stat should be <= {0}";
public static string LMemoryStatAffectionHT0 { get; set; } = "Untraded: Handling Trainer Affection should be 0.";
public static string LMemoryStatAffectionOT0 { get; set; } = "OT Affection should be 0.";
public static string LMemoryStatFriendshipHT0 { get; set; } = "Untraded: Handling Trainer Friendship should be 0.";
public static string LMemoryStatFriendshipOTBaseEvent { get; set; } = "Event OT Friendship does not match base friendship.";
public static string LMetDetailTimeOfDay { get; set; } = "Met Time of Day value is not within the expected range.";
public static string LMemoryStatFullness { get; set; } = "Fullness should be {0}.";
public static string LMemoryStatEnjoyment { get; set; } = "Enjoyment should be {0}.";
public static string LMoveEggFIncompatible0_1 { get; set; } = "{0} Inherited Move. Incompatible with {1} inherited moves.";
public static string LMoveEggIncompatible { get; set; } = "Egg Move. Incompatible with event Egg moves.";
public static string LMoveEggIncompatibleEvent { get; set; } = "Event Egg Move. Incompatible with normal Egg moves.";
public static string LMoveEggInherited { get; set; } = "Inherited Egg move.";
public static string LMoveEggInheritedTutor { get; set; } = "Inherited tutor move.";
public static string LMoveEggInvalid { get; set; } = "Not an expected Egg move.";
public static string LMoveEggInvalidEvent { get; set; } = "Egg Move. Not expected in an event Egg.";
public static string LMoveEggInvalidEventLevelUp { get; set; } = "Inherited move learned by Level-up. Not expected in an event Egg.";
public static string LMoveEggInvalidEventLevelUpGift { get; set; } = "Inherited move learned by Level-up. Not expected in a gift Egg.";
public static string LMoveEggInvalidEventTMHM { get; set; } = "Inherited TM/HM move. Not expected in an event Egg.";
public static string LMoveEggInvalidEventTutor { get; set; } = "Inherited tutor move. Not expected in an event Egg.";
public static string LMoveEggLevelUp { get; set; } = "Inherited move learned by Level-up.";
public static string LMoveEggMissing { get; set; } = "Event Egg move missing.";
public static string LMoveEggMoveGift { get; set; } = "Egg Move. Not expected in a gift Egg.";
public static string LMoveEggTMHM { get; set; } = "Inherited TM/HM move.";
public static string LMoveEventEggLevelUp { get; set; } = "Inherited move learned by Level-up. Incompatible with event Egg moves.";
public static string LMoveEvoFCombination_0 { get; set; } = "Moves combinations is not compatible with {0} evolution.";
public static string LMoveEvoFHigher { get; set; } = "Incompatible evolution moves. {1} Move learned at a higher level than other {0} moves.";
public static string LMoveEvoFLower { get; set; } = "Incompatible evolution moves. {0} Move learned at a lower level than other {1} moves.";
public static string LMoveFDefault_0 { get; set; } = "Default move in Generation {0}.";
public static string LMoveFExpect_0 { get; set; } = "Expected the following Moves: {0}";
public static string LMoveFExpectSingle_0 { get; set; } = "Expected: {0}";
public static string LMoveFLevelUp_0 { get; set; } = "Learned by Level-up in Generation {0}.";
public static string LMoveFTMHM_0 { get; set; } = "Learned by TM/HM in Generation {0}.";
public static string LMoveFTutor_0 { get; set; } = "Learned by Move Tutor in Generation {0}.";
public static string LMoveKeldeoMismatch { get; set; } = "Keldeo Move/Form mismatch.";
public static string LMoveNincada { get; set; } = "Only one Ninjask move allowed.";
public static string LMoveNincadaEvo { get; set; } = "Learned by evolving Nincada into Ninjask.";
public static string LMoveNincadaEvoF_0 { get; set; } = "Learned by evolving Nincada into Ninjask in Generation {0}.";
public static string LMovePPExpectHealed_0 { get; set; } = "Move {0} PP is below the amount expected.";
public static string LMovePPTooHigh_0 { get; set; } = "Move {0} PP is above the amount allowed.";
public static string LMovePPUpsTooHigh_0 { get; set; } = "Move {0} PP Ups is above the amount allowed.";
public static string LMoveSourceShared { get; set; } = "Shared Non-Relearn Move.";
public static string LMoveSourceSharedF { get; set; } = "Shared Non-Relearn Move in Generation {0}.";
public static string LMoveRelearnDexNav { get; set; } = "Not an expected DexNav move.";
public static string LMoveRelearnUnderground { get; set; } = "Not an expected Underground egg move.";
public static string LMoveRelearnEgg { get; set; } = "Base Egg move.";
public static string LMoveRelearnEggMissing { get; set; } = "Base Egg move missing.";
public static string LMoveRelearnFExpect_0 { get; set; } = "Expected the following Relearn Moves: {0} ({1})";
public static string LMoveRelearnFMiss_0 { get; set; } = "Relearn Moves missing: {0}";
public static string LMoveRelearnInvalid { get; set; } = "Not an expected Relearnable move.";
public static string LMoveRelearnNone { get; set; } = "Expected no Relearn Move in slot.";
public static string LMoveShopAlphaMoveShouldBeMastered { get; set; } = "Alpha Move should be marked as mastered.";
public static string LMoveShopAlphaMoveShouldBeOther { get; set; } = "Alpha encounter cannot be found with this Alpha Move.";
public static string LMoveShopAlphaMoveShouldBeZero { get; set; } = "Only Alphas may have an Alpha Move set.";
public static string LMoveShopMasterInvalid_0 { get; set; } = "Cannot manually master {0}: not permitted to master.";
public static string LMoveShopMasterNotLearned_0 { get; set; } = "Cannot manually master {0}: not in possible learned level up moves.";
public static string LMoveShopPurchaseInvalid_0 { get; set; } = "Cannot purchase {0} from the move shop.";
public static string LMoveSourceDefault { get; set; } = "Default move.";
public static string LMoveSourceDuplicate { get; set; } = "Duplicate Move.";
public static string LMoveSourceEgg { get; set; } = "Egg Move.";
public static string LMoveSourceEggEvent { get; set; } = "Event Egg Move.";
public static string LMoveSourceEmpty { get; set; } = "Empty Move.";
public static string LMoveSourceInvalid { get; set; } = "Invalid Move.";
public static string LMoveSourceInvalidSketch { get; set; } = "Invalid Move (Sketch).";
public static string LMoveSourceLevelUp { get; set; } = "Learned by Level-up.";
public static string LMoveSourceRelearn { get; set; } = "Relearnable Move.";
public static string LMoveSourceSpecial { get; set; } = "Special Non-Relearn Move.";
public static string LMoveSourceTMHM { get; set; } = "Learned by TM/HM.";
public static string LMoveSourceTutor { get; set; } = "Learned by Move Tutor.";
public static string LMoveSourceTR { get; set; } = "Unexpected Technical Record Learned flag: {0}";
public static string LNickFlagEggNo { get; set; } = "Egg must be not nicknamed.";
public static string LNickFlagEggYes { get; set; } = "Egg must be nicknamed.";
public static string LNickInvalidChar { get; set; } = "Cannot be given this Nickname.";
public static string LNickLengthLong { get; set; } = "Nickname too long.";
public static string LNickLengthShort { get; set; } = "Nickname is empty.";
public static string LNickMatchLanguage { get; set; } = "Nickname matches species name.";
public static string LNickMatchLanguageEgg { get; set; } = "Egg matches language Egg name.";
public static string LNickMatchLanguageEggFail { get; set; } = "Egg name does not match language Egg name.";
public static string LNickMatchLanguageFail { get; set; } = "Nickname does not match species name.";
public static string LNickMatchLanguageFlag { get; set; } = "Nickname flagged, matches species name.";
public static string LNickMatchNoOthers { get; set; } = "Nickname does not match another species name.";
public static string LNickMatchNoOthersFail { get; set; } = "Nickname matches another species name (+language).";
public static string LOTLanguage { get; set; } = "Language ID should be {0}, not {1}.";
public static string LOTLong { get; set; } = "OT Name too long.";
public static string LOTShort { get; set; } = "OT Name too short.";
public static string LOTSuspicious { get; set; } = "Suspicious Original Trainer details.";
public static string LOT_IDEqual { get; set; } = "TID16 and SID16 are equal.";
public static string LOT_IDs0 { get; set; } = "TID16 and SID16 are 0.";
public static string LOT_SID0 { get; set; } = "SID16 is zero.";
public static string LOT_SID0Invalid { get; set; } = "SID16 should be 0.";
public static string LOT_TID0 { get; set; } = "TID16 is zero.";
public static string LOT_IDInvalid { get; set; } = "TID16 and SID16 combination is not possible.";
public static string LPIDEncryptWurmple { get; set; } = "Wurmple evolution Encryption Constant mismatch.";
public static string LPIDEncryptZero { get; set; } = "Encryption Constant is not set.";
public static string LPIDEqualsEC { get; set; } = "Encryption Constant matches PID.";
public static string LPIDGenderMatch { get; set; } = "Gender matches PID.";
public static string LPIDGenderMismatch { get; set; } = "PID-Gender mismatch.";
public static string LPIDNatureMatch { get; set; } = "Nature matches PID.";
public static string LPIDNatureMismatch { get; set; } = "PID-Nature mismatch.";
public static string LPIDTypeMismatch { get; set; } = "PID+ correlation does not match what was expected for the Encounter's type.";
public static string LPIDZero { get; set; } = "PID is not set.";
public static string LPokerusDaysTooHigh_0 { get; set; } = "Pokérus Days Remaining value is too high; expected <= {0}.";
public static string LPokerusStrainUnobtainable_0 { get; set; } = "Pokérus Strain {0} cannot be obtained.";
public static string LRibbonAllValid { get; set; } = "All ribbons accounted for.";
public static string LRibbonEgg { get; set; } = "Can't receive Ribbon(s) as an Egg.";
public static string LRibbonFInvalid_0 { get; set; } = "Invalid Ribbons: ";
public static string LRibbonFMissing_0 { get; set; } = "Missing Ribbons: ";
public static string LRibbonMarkingFInvalid_0 { get; set; } = "Invalid Marking: {0}";
public static string LRibbonMarkingAffixedF_0 { get; set; } = "Invalid Affixed Ribbon/Marking: {0}";
public static string LStatDynamaxInvalid { get; set; } = "Dynamax Level is not within the expected range.";
public static string LStatIncorrectHeight { get; set; } = "Calculated Height does not match stored value.";
public static string LStatIncorrectHeightCopy { get; set; } = "Copy Height does not match the original value.";
public static string LStatIncorrectHeightValue { get; set; } = "Height does not match the expected value.";
public static string LStatIncorrectWeight { get; set; } = "Calculated Weight does not match stored value.";
public static string LStatIncorrectWeightValue { get; set; } = "Weight does not match the expected value.";
public static string LStatInvalidHeightWeight { get; set; } = "Height / Weight values are statistically improbable.";
public static string LStatIncorrectCP { get; set; } = "Calculated CP does not match stored value.";
public static string LStatGigantamaxInvalid { get; set; } = "Gigantamax Flag mismatch.";
public static string LStatGigantamaxValid { get; set; } = "Gigantamax Flag was changed via Max Soup.";
public static string LStatNatureInvalid { get; set; } = "Stat Nature is not within the expected range.";
public static string LStatBattleVersionInvalid { get; set; } = "Battle Version is not within the expected range.";
public static string LStatNobleInvalid { get; set; } = "Noble Flag mismatch.";
public static string LStatAlphaInvalid { get; set; } = "Alpha Flag mismatch.";
public static string LStoredSourceEgg { get; set; } = "Egg must be in Box or Party.";
public static string LStoredSourceInvalid_0 { get; set; } = "Invalid Stored Source: {0}";
public static string LSuperComplete { get; set; } = "Super Training complete flag mismatch.";
public static string LSuperDistro { get; set; } = "Distribution Super Training missions are not released.";
public static string LSuperEgg { get; set; } = "Can't Super Train an Egg.";
public static string LSuperNoComplete { get; set; } = "Can't have active Super Training complete flag for origins.";
public static string LSuperNoUnlocked { get; set; } = "Can't have active Super Training unlocked flag for origins.";
public static string LSuperUnavailable { get; set; } = "Super Training missions are not available in games visited.";
public static string LSuperUnused { get; set; } = "Unused Super Training Flag is flagged.";
public static string LTeraTypeIncorrect { get; set; } = "Tera Type does not match the expected value.";
public static string LTeraTypeMismatch { get; set; } = "Tera Type does not match either of the default types.";
public static string LTradeNotAvailable { get; set; } = "Encounter cannot be traded to the active trainer.";
public static string LTrainerIDNoSeed { get; set; } = "Trainer ID is not obtainable from any RNG seed.";
public static string LTransferBad { get; set; } = "Incorrectly transferred from previous generation.";
public static string LTransferCurrentHandlerInvalid { get; set; } = "Invalid Current handler value, trainer details for save file expected another value.";
public static string LTransferEgg { get; set; } = "Can't transfer Eggs between Generations.";
public static string LTransferEggLocationTransporter { get; set; } = "Invalid Met Location, expected Poké Transfer.";
public static string LTransferEggMetLevel { get; set; } = "Invalid Met Level for transfer.";
public static string LTransferEggVersion { get; set; } = "Can't transfer Eggs to this game.";
public static string LTransferFlagIllegal { get; set; } = "Flagged as illegal by the game (glitch abuse).";
public static string LTransferHTFlagRequired { get; set; } = "Current handler cannot be the OT.";
public static string LTransferHTMismatchName { get; set; } = "Handling trainer does not match the expected trainer name.";
public static string LTransferHTMismatchGender { get; set; } = "Handling trainer does not match the expected trainer gender.";
public static string LTransferHTMismatchLanguage { get; set; } = "Handling trainer does not match the expected trainer language.";
public static string LTransferMet { get; set; } = "Invalid Met Location, expected Poké Transfer or Crown.";
public static string LTransferNotPossible { get; set; } = "Unable to transfer into current format from origin format.";
public static string LTransferMetLocation { get; set; } = "Invalid Transfer Met Location.";
public static string LTransferMove { get; set; } = "Incompatible transfer move.";
public static string LTransferMoveG4HM { get; set; } = "Defog and Whirlpool. One of the two moves should have been removed before transferred to Generation 5.";
public static string LTransferMoveHM { get; set; } = "Generation {0} HM. Should have been removed before transferred to Generation {1}.";
public static string LTransferNature { get; set; } = "Invalid Nature for transfer Experience.";
public static string LTransferObedienceLevel { get; set; } = "Invalid Obedience Level.";
public static string LTransferOriginFInvalid0_1 { get; set; } = "{0} origin cannot exist in the currently loaded ({1}) save file.";
public static string LTransferPIDECBitFlip { get; set; } = "PID should be equal to EC [with top bit flipped]!";
public static string LTransferPIDECEquals { get; set; } = "PID should be equal to EC!";
public static string LTransferPIDECXor { get; set; } = "Encryption Constant matches shinyxored PID.";
public static string LTransferTrackerMissing { get; set; } = "Pokémon HOME Transfer Tracker is missing.";
public static string LTransferTrackerShouldBeZero { get; set; } = "Pokémon HOME Transfer Tracker should be 0.";
public static string LTrashBytesExpected_0 { get; set; } = "Expected Trash Bytes: {0}";
public static string LTrashBytesExpected { get; set; } = "Expected Trash Bytes.";
public static string LTrashBytesMismatchInitial { get; set; } = "Expected initial trash bytes to match the encounter.";
public static string LTrashBytesMissingTerminator { get; set; } = "Final terminator missing.";
public static string LTrashBytesShouldBeEmpty { get; set; } = "Trash Bytes should be cleared.";
public static string LTrashBytesUnexpected { get; set; } = "Unexpected Trash Bytes.";
#endregion
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
@ -11,59 +10,70 @@ namespace PKHeX.Core;
/// </summary>
public static class LegalityFormatting
{
public static ILegalityFormatter Formatter { private get; set; } = new BaseLegalityFormatter();
/// <summary>
/// Creates a report message with optional verbosity for in-depth analysis.
/// </summary>
/// <param name="la">Legality result to format</param>
/// <param name="verbose">Include all details in the parse, including valid check messages.</param>
/// <returns>Single line string</returns>
public static string Report(this LegalityAnalysis la, bool verbose = false) => verbose ? GetVerboseLegalityReport(la) : GetLegalityReport(la);
public static ILegalityFormatter Formatter { private get; set; } = new BaseLegalityFormatter();
public static string GetLegalityReport(LegalityAnalysis la) => Formatter.GetReport(la);
public static string GetVerboseLegalityReport(LegalityAnalysis la) => Formatter.GetReportVerbose(la);
public static void AddSecondaryChecksValid(IEnumerable<CheckResult> results, List<string> lines)
public static string Report(this LegalityAnalysis la, bool verbose = false)
{
var outputLines = results
.Where(chk => chk.Valid && chk.Comment != L_AValid)
.OrderBy(chk => chk.Judgement) // Fishy sorted to top
.Select(chk => chk.Format(L_F0_1));
lines.AddRange(outputLines);
var localizer = LegalityLocalizationContext.Create(la);
return Report(localizer, verbose);
}
public static void AddSecondaryChecksInvalid(IReadOnlyList<CheckResult> results, List<string> lines)
/// <inheritdoc cref="Report(LegalityAnalysis, bool)"/>
public static string Report(this LegalityLocalizationContext localizer, bool verbose) => verbose ? GetVerboseLegalityReport(localizer) : GetLegalityReport(localizer);
/// <inheritdoc cref="Report(LegalityAnalysis, bool)"/>
public static string Report(this LegalityAnalysis la, string language, bool verbose = false)
{
var localizer = LegalityLocalizationContext.Create(la, language);
return localizer.Report(verbose);
}
public static string GetLegalityReport(LegalityLocalizationContext la) => Formatter.GetReport(la);
public static string GetVerboseLegalityReport(LegalityLocalizationContext la) => Formatter.GetReportVerbose(la);
public static void AddSecondaryChecksValid(LegalityLocalizationContext la, IEnumerable<CheckResult> results, List<string> lines)
{
var outputLines = results
.Where(chk => chk.Valid && chk.IsNotGeneric())
.OrderBy(chk => chk.Judgement); // Fishy sorted to top
foreach (var chk in outputLines)
lines.Add(la.Humanize(chk));
}
public static void AddSecondaryChecksInvalid(LegalityLocalizationContext la, IReadOnlyList<CheckResult> results, List<string> lines)
{
foreach (var chk in results)
{
if (chk.Valid)
continue;
lines.Add(chk.Format(L_F0_1));
lines.Add(la.Humanize(chk));
}
}
public static void AddRelearn(ReadOnlySpan<MoveResult> relearn, List<string> lines, bool state, PKM pk, EvolutionHistory history)
public static void AddRelearn(LegalityLocalizationContext la, ReadOnlySpan<MoveResult> relearn, List<string> lines, bool state)
{
for (int i = 0; i < relearn.Length; i++)
{
var move = relearn[i];
if (move.Valid == state)
lines.Add(move.Format(L_F0_RM_1_2, i + 1, pk, history));
lines.Add(la.FormatRelearn(move, i + 1));
}
}
public static void AddMoves(ReadOnlySpan<MoveResult> moves, List<string> lines, in int currentFormat, bool state, PKM pk, EvolutionHistory history)
public static void AddMoves(LegalityLocalizationContext la, ReadOnlySpan<MoveResult> moves, List<string> lines, in byte currentFormat, bool state)
{
for (int i = 0; i < moves.Length; i++)
{
var move = moves[i];
if (move.Valid != state)
continue;
var msg = move.Format(L_F0_M_1_2, i + 1, pk, history);
var gen = move.Generation;
if (currentFormat != gen && gen != 0)
msg += $" [Gen{gen}]";
var msg = la.FormatMove(move, i + 1, currentFormat);
lines.Add(msg);
}
}
@ -71,41 +81,44 @@ public static void AddMoves(ReadOnlySpan<MoveResult> moves, List<string> lines,
/// <summary>
/// Adds information about the <see cref="LegalityAnalysis.EncounterMatch"/> to the <see cref="lines"/>.
/// </summary>
public static void AddEncounterInfo(LegalityAnalysis la, List<string> lines)
public static void AddEncounterInfo(LegalityLocalizationContext l, List<string> lines)
{
var la = l.Analysis;
var enc = la.EncounterOriginal;
var display = l.Settings.Encounter;
// Name
lines.Add(string.Format(L_FEncounterType_0, enc.GetEncounterName()));
lines.Add(string.Format(display.Format, display.EncounterType, enc.GetEncounterName(l.Strings.specieslist)));
if (enc is MysteryGift g)
lines.Add(g.CardHeader);
// Location
var loc = enc.GetEncounterLocation();
if (!string.IsNullOrEmpty(loc))
lines.Add(string.Format(L_F0_1, L_XLocation, loc));
lines.Add(string.Format(display.Format, display.Location, loc));
// Version
if (enc.Generation <= 2)
lines.Add(string.Format(L_F0_1, nameof(GameVersion), enc.Version));
lines.Add(string.Format(display.Format, display.Version, enc.Version));
// PID/IV
AddEncounterInfoPIDIV(la, lines);
AddEncounterInfoPIDIV(l, lines);
}
public static void AddEncounterInfoPIDIV(LegalityAnalysis la, List<string> lines)
public static void AddEncounterInfoPIDIV(LegalityLocalizationContext l, List<string> lines)
{
var strings = l.Settings;
var la = l.Analysis;
var info = la.Info;
if (!info.PIDParsed)
info.PIDIV = MethodFinder.Analyze(la.Entity);
AddEncounterInfoPIDIV(lines, info);
AddEncounterInfoPIDIV(strings, lines, info);
}
private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
private static void AddEncounterInfoPIDIV(LegalityLocalizationSet strings, List<string> lines, LegalInfo info)
{
var pidiv = info.PIDIV;
var type = pidiv.Type;
var msgType = string.Format(L_FPIDType_0, type);
var msgType = string.Format(strings.Encounter.Format, strings.Encounter.PIDType, type);
var enc = info.EncounterOriginal;
if (enc is IRandomCorrelationEvent3 r3)
{
@ -128,7 +141,7 @@ private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
{
if (type is not PIDType.Pokewalker)
return;
var line = GetLinePokewalkerSeed(info);
var line = GetLinePokewalkerSeed(info, strings);
lines.Add(line);
}
else if (enc is PCD pcd)
@ -137,7 +150,7 @@ private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
if (gift is { HasPID: false }) // tick rand
{
var ticks = ARNG.Prev(info.Entity.EncryptionConstant);
var line = string.Format(L_FOriginSeed_0, ticks.ToString("X8"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, ticks.ToString("X8"));
line += $" [{ticks / 524_288f:F2}]"; // seconds?
lines.Add(line);
}
@ -151,7 +164,7 @@ private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
var initial = ClassicEraRNG.SeekInitialSeedForIVs(ivs, (uint)date.Year, (uint)date.Month, (uint)date.Day, out var origin);
var components = ClassicEraRNG.DecomposeSeed(initial, (uint)date.Year, (uint)date.Month, (uint)date.Day);
AppendInitialDateTime4(lines, initial, origin, components);
AppendInitialDateTime4(lines, initial, origin, components, strings.Encounter);
if (components.IsInvalid())
lines.Add("INVALID");
}
@ -160,13 +173,13 @@ private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
{
if (Daycare3.TryGetOriginSeed(info.Entity, out var day3))
{
var line = string.Format(L_FOriginSeed_0, day3.Origin.ToString("X8"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, day3.Origin.ToString("X8"));
lines.Add(line);
lines.Add($"Initial: 0x{day3.Initial:X8}, Frame: {day3.Advances + 1}"); // frames are 1-indexed
lines.Add(string.Format(strings.Encounter.FrameInitial, day3.Initial.ToString("X8"), day3.Advances + 1)); // frames are 1-indexed
var sb = new StringBuilder();
AppendFrameTimeStamp3(day3.Advances, sb);
lines.Add($"Time: {sb}");
AppendFrameTimeStamp3(day3.Advances, sb, strings.Encounter);
lines.Add(string.Format(strings.Encounter.Format, strings.Encounter.Time, sb));
}
}
return;
@ -174,43 +187,43 @@ private static void AddEncounterInfoPIDIV(List<string> lines, LegalInfo info)
if (pidiv.IsSeed64())
{
var line = string.Format(L_FOriginSeed_0, pidiv.Seed64.ToString("X16"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, pidiv.Seed64.ToString("X16"));
lines.Add(line);
return;
}
if (enc is IEncounterSlot34 s)
{
var line = GetLineSlot34(info, pidiv, s);
var line = GetLineSlot34(info, strings, pidiv, s);
lines.Add(line);
}
else
{
var seed = pidiv.OriginSeed;
var line = string.Format(L_FOriginSeed_0, seed.ToString("X8"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, seed.ToString("X8"));
if (pidiv.Mutated is not 0 && pidiv.OriginSeed != pidiv.EncounterSeed)
line += $" [{pidiv.EncounterSeed:X8}]";
lines.Add(line);
}
if (enc is EncounterSlot3 or EncounterStatic3)
AppendDetailsFrame3(info, lines);
AppendDetailsFrame3(info, lines, strings.Encounter);
else if (enc is EncounterSlot4 or EncounterStatic4)
AppendDetailsDate4(info, lines);
AppendDetailsDate4(info, lines, strings.Encounter);
}
private static string GetLinePokewalkerSeed(LegalInfo info)
private static string GetLinePokewalkerSeed(LegalInfo info, LegalityLocalizationSet strings)
{
var pk = info.Entity;
var result = PokewalkerRNG.GetLeastEffortSeed((uint)pk.IV_HP, (uint)pk.IV_ATK, (uint)pk.IV_DEF, (uint)pk.IV_SPA, (uint)pk.IV_SPD, (uint)pk.IV_SPE);
var line = string.Format(L_FOriginSeed_0, result.Seed.ToString("X8"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, result.Seed.ToString("X8"));
line += $" [{result.Type} @ {result.PriorPoke}]";
return line;
}
private static string GetLineSlot34(LegalInfo info, PIDIV pidiv, IEncounterSlot34 s)
private static string GetLineSlot34(LegalInfo info, LegalityLocalizationSet strings, PIDIV pidiv, IEncounterSlot34 s)
{
var lead = pidiv.Lead;
var seed = !info.FrameMatches || lead == LeadRequired.Invalid ? pidiv.OriginSeed : pidiv.EncounterSeed;
var line = string.Format(L_FOriginSeed_0, seed.ToString("X8"));
var line = string.Format(strings.Encounter.Format, strings.Encounter.OriginSeed, seed.ToString("X8"));
if (lead != LeadRequired.None)
{
if (lead is LeadRequired.Static)
@ -220,7 +233,7 @@ private static string GetLineSlot34(LegalInfo info, PIDIV pidiv, IEncounterSlot3
else
line += $" [{s.SlotNumber}]";
line += $" ({lead.Localize()})";
line += $" ({lead.Localize(strings.Lines)})";
}
else
{
@ -230,7 +243,7 @@ private static string GetLineSlot34(LegalInfo info, PIDIV pidiv, IEncounterSlot3
return line;
}
private static void AppendDetailsDate4(LegalInfo info, List<string> lines)
private static void AppendDetailsDate4(LegalInfo info, List<string> lines, EncounterDisplayLocalization loc)
{
var pidiv = info.PIDIV;
if (pidiv.Type is not (PIDType.Method_1 or PIDType.ChainShiny))
@ -244,34 +257,34 @@ private static void AppendDetailsDate4(LegalInfo info, List<string> lines)
var entity = info.Entity;
var date = entity.MetDate ?? new DateOnly(2000, 1, 1);
var initialSeed = ClassicEraRNG.SeekInitialSeed((uint)date.Year, (uint)date.Month, (uint)date.Day, seed);
AppendInitialDateTime4(lines, initialSeed, seed, date);
AppendInitialDateTime4(lines, initialSeed, seed, date, loc);
}
private static void AppendInitialDateTime4(List<string> lines, uint initialSeed, uint origin, DateOnly date)
private static void AppendInitialDateTime4(List<string> lines, uint initialSeed, uint origin, DateOnly date, EncounterDisplayLocalization loc)
{
var decompose = ClassicEraRNG.DecomposeSeed(initialSeed, (uint)date.Year, (uint)date.Month, (uint)date.Day);
AppendInitialDateTime4(lines, initialSeed, origin, decompose);
AppendInitialDateTime4(lines, initialSeed, origin, decompose, loc);
}
private static void AppendInitialDateTime4(List<string> lines, uint initialSeed, uint origin, InitialSeedComponents4 decompose)
private static void AppendInitialDateTime4(List<string> lines, uint initialSeed, uint origin, InitialSeedComponents4 decompose, EncounterDisplayLocalization loc)
{
var advances = LCRNG.GetDistance(initialSeed, origin);
lines.Add($"{decompose.Year+2000:0000}-{decompose.Month:00}-{decompose.Day:00} @ {decompose.Hour:00}:{decompose.Minute:00}:{decompose.Second:00} - {decompose.Delay}");
lines.Add($"Initial: 0x{initialSeed:X8}, Frame: {advances + 1}"); // frames are 1-indexed
lines.Add(string.Format(loc.FrameInitial, initialSeed.ToString("X8"), advances + 1)); // frames are 1-indexed
}
private static void AppendDetailsFrame3(LegalInfo info, List<string> lines)
private static void AppendDetailsFrame3(LegalInfo info, List<string> lines, EncounterDisplayLocalization loc)
{
var pidiv = info.PIDIV;
var pk = info.Entity;
var enc = info.EncounterOriginal;
var seed = enc is EncounterSlot3 && info.FrameMatches ? pidiv.EncounterSeed : pidiv.OriginSeed;
var (initialSeed, advances) = GetInitialSeed3(seed, pk.Version);
lines.Add($"Initial: 0x{initialSeed:X8}, Frame: {advances + 1}"); // frames are 1-indexed
lines.Add(string.Format(loc.FrameInitial, initialSeed.ToString("X8"), advances + 1)); // frames are 1-indexed
var sb = new StringBuilder();
AppendFrameTimeStamp3(advances, sb);
lines.Add($"Time: {sb}");
AppendFrameTimeStamp3(advances, sb, loc);
lines.Add(string.Format(loc.Format, loc.Time, sb));
// Try appending the TID frame if it originates from Emerald.
if (pk.Version is not GameVersion.E)
@ -281,10 +294,10 @@ private static void AppendDetailsFrame3(LegalInfo info, List<string> lines)
var tidAdvances = LCRNG.GetDistance(tidSeed, seed);
if (tidAdvances >= advances)
return; // only show if it makes sense to
lines.Add($"New Game: 0x{tidSeed:X8}, Frame: {tidAdvances + 1}"); // frames are 1-indexed
lines.Add(string.Format(loc.FrameNewGame, tidSeed.ToString("X8"), tidAdvances + 1)); // frames are 1-indexed
sb.Clear();
AppendFrameTimeStamp3(tidAdvances, sb);
lines.Add($"Time: {sb}");
AppendFrameTimeStamp3(tidAdvances, sb, loc);
lines.Add(string.Format(loc.Format, loc.Time, sb));
}
/// <summary>
@ -292,7 +305,8 @@ private static void AppendDetailsFrame3(LegalInfo info, List<string> lines)
/// </summary>
/// <param name="frame">Frames elapsed since the initial seed.</param>
/// <param name="sb">StringBuilder to append the timestamp to.</param>
private static void AppendFrameTimeStamp3(uint frame, StringBuilder sb)
/// <param name="loc">Localization strings for formatting.</param>
private static void AppendFrameTimeStamp3(uint frame, StringBuilder sb, EncounterDisplayLocalization loc)
{
var time = TimeSpan.FromSeconds((double)frame / 60);
if (time.TotalHours >= 1)
@ -303,7 +317,7 @@ private static void AppendFrameTimeStamp3(uint frame, StringBuilder sb)
sb.Append($"{time.Milliseconds / 10:00}");
if (time.TotalDays >= 1)
sb.Append($" (days: {(int)time.TotalDays})");
sb.AppendFormat(loc.SuffixDays, (int)time.TotalDays);
}
private static (uint Seed, uint Advances) GetInitialSeed3(uint seed, GameVersion game)
@ -329,25 +343,24 @@ private static (uint Seed, uint Advances) GetInitialSeed3(uint seed, GameVersion
return (nearest16, ctr);
}
private static string Localize(this LeadRequired lead)
private static string Localize(this LeadRequired lead, LegalityCheckLocalization localization)
{
if (lead is LeadRequired.Invalid)
return "❌";
var (ability, isFail, condition) = lead.GetDisplayAbility();
var abilities = GameInfo.Strings.Ability;
var name = abilities[(int)ability];
var result = isFail ? string.Format(L_F0_1, name, "❌") : name;
var result = isFail ? string.Format(localization.F0_1, name, "❌") : name;
if (condition != EncounterTriggerCondition.None)
result += $"-{condition}";
return result;
}
public static string GetEncounterName(this IEncounterable enc)
public static string GetEncounterName(this IEncounterable enc, ReadOnlySpan<string> speciesNames)
{
var str = ParseSettings.SpeciesStrings;
// Shouldn't ever be out of range, but just in case.
var species = enc.Species;
var name = (uint)species < str.Count ? str[species] : species.ToString();
var name = (uint)species < speciesNames.Length ? speciesNames[species] : species.ToString();
return $"{enc.LongName} ({name})";
}

View File

@ -1,7 +1,6 @@
using System;
using System.Text;
using static PKHeX.Core.LearnMethod;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
@ -14,9 +13,9 @@ namespace PKHeX.Core;
public readonly record struct MoveLearnInfo(LearnMethod Method, LearnEnvironment Environment, byte Argument = 0)
{
/// <inheritdoc cref="Summarize(StringBuilder, ReadOnlySpan{char})"/>
public void Summarize(StringBuilder sb)
public void Summarize(StringBuilder sb, MoveSourceLocalization strings)
{
var localized = GetLocalizedMethod();
var localized = GetLocalizedMethod(strings);
Summarize(sb, localized);
}
@ -34,31 +33,31 @@ private void Summarize(StringBuilder sb, ReadOnlySpan<char> localizedMethod)
sb.Append($" @ lv{Argument}");
}
private string GetLocalizedMethod() => Method switch
private string GetLocalizedMethod(MoveSourceLocalization strings) => Method switch
{
Empty => LMoveSourceEmpty,
Relearn => LMoveSourceRelearn,
Initial => LMoveSourceDefault,
LevelUp => LMoveSourceLevelUp,
TMHM => LMoveSourceTMHM,
Tutor => LMoveSourceTutor,
Sketch => LMoveSourceShared,
EggMove => LMoveRelearnEgg,
InheritLevelUp => LMoveEggInherited,
Empty => strings.SourceEmpty,
Relearn => strings.SourceRelearn,
Initial => strings.SourceDefault,
LevelUp => strings.SourceLevelUp,
TMHM => strings.SourceTMHM,
Tutor => strings.SourceTutor,
Sketch => strings.SourceShared,
EggMove => strings.RelearnEgg,
InheritLevelUp => strings.EggInherited,
HOME => LMoveSourceSpecial,
Evolution => LMoveSourceSpecial,
Encounter => LMoveSourceSpecial,
SpecialEgg => LMoveSourceSpecial,
ShedinjaEvo => LMoveSourceSpecial,
HOME => strings.SourceSpecial,
Evolution => strings.SourceSpecial,
Encounter => strings.SourceSpecial,
SpecialEgg => strings.SourceSpecial,
ShedinjaEvo => strings.SourceSpecial,
Shared => LMoveSourceShared,
Shared => strings.SourceShared,
// Invalid
None => LMoveSourceInvalid,
Unobtainable or UnobtainableExpect => LMoveSourceInvalid,
Duplicate => LMoveSourceDuplicate,
EmptyInvalid => LMoveSourceEmpty,
None => strings.SourceInvalid,
Unobtainable or UnobtainableExpect => strings.SourceInvalid,
Duplicate => strings.SourceDuplicate,
EmptyInvalid => strings.SourceEmpty,
_ => throw new ArgumentOutOfRangeException(nameof(Method), Method, null),
};

View File

@ -18,18 +18,22 @@ namespace PKHeX.Core;
internal MoveResult(LearnMethod method, LearnEnvironment game) : this(new MoveLearnInfo(method, game), Generation: game.GetGeneration()) { }
private MoveResult(LearnMethod method) : this(new MoveLearnInfo(method, LearnEnvironment.None)) { }
public string Summary(ISpeciesForm current, EvolutionHistory history)
public string Summary(in LegalityLocalizationContext ctx)
{
var sb = new StringBuilder(48);
Info.Summarize(sb);
Info.Summarize(sb, ctx.Settings.Moves);
if (Info.Method.HasExpectedMove())
{
var name = ParseSettings.MoveStrings[Expect];
var str = LegalityCheckStrings.LMoveFExpectSingle_0;
var str = ctx.Settings.Lines.MoveFExpectSingle_0;
sb.Append(' ').AppendFormat(str, name);
return sb.ToString();
}
var la = ctx.Analysis;
var history = la.Info.EvoChainsAllGens;
var current = la.Entity;
var detail = GetDetail(history);
if (detail.Species == 0)
return sb.ToString();
@ -57,9 +61,6 @@ private EvoCriteria GetDetail(EvolutionHistory history)
public bool IsRelearn => Info.Method.IsRelearn();
public Severity Judgement => Valid ? Severity.Valid : Severity.Invalid;
public string Rating => Judgement.Description();
public string Format(string format, int index, PKM pk, EvolutionHistory history) => string.Format(format, Rating, index, Summary(pk, history));
public static MoveResult Initial(LearnEnvironment game) => new(LearnMethod.Initial, game);
public static readonly MoveResult Relearn = new(LearnMethod.Relearn);

View File

@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.LegalityAnalyzers;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -99,7 +99,7 @@ public LegalityAnalysis(PKM pk, IPersonalInfo pi, StorageSlotType source = Ignor
{
EncounterFinder.FindVerifiedEncounter(pk, Info);
if (!pk.IsOriginValid)
AddLine(Severity.Invalid, LEncConditionBadSpecies, CheckIdentifier.GameOrigin);
AddLine(Severity.Invalid, EncConditionBadSpecies, CheckIdentifier.GameOrigin);
GetParseMethod()();
Valid = Parse.TrueForAll(chk => chk.Valid)
@ -107,7 +107,7 @@ public LegalityAnalysis(PKM pk, IPersonalInfo pi, StorageSlotType source = Ignor
&& MoveResult.AllValid(Info.Relearn);
if (!Valid && IsPotentiallyMysteryGift(Info, pk))
AddLine(Severity.Invalid, LFatefulGiftMissing, CheckIdentifier.Fateful);
AddLine(Severity.Invalid, FatefulGiftMissing, CheckIdentifier.Fateful);
Parsed = true;
}
#if SUPPRESS
@ -130,7 +130,7 @@ public LegalityAnalysis(PKM pk, IPersonalInfo pi, StorageSlotType source = Ignor
p = MoveResult.Unobtainable();
}
AddLine(Severity.Invalid, L_AError, CheckIdentifier.Misc);
AddLine(Severity.Invalid, Error, CheckIdentifier.Misc);
}
#endif
}
@ -261,7 +261,7 @@ private void ParsePK9()
/// <param name="s">Check severity</param>
/// <param name="c">Check comment</param>
/// <param name="i">Check type</param>
internal void AddLine(Severity s, string c, CheckIdentifier i) => AddLine(new CheckResult(s, i, c));
internal void AddLine(Severity s, LegalityCheckResultCode c, CheckIdentifier i) => AddLine(CheckResult.Get(s, i, c));
/// <summary>
/// Adds a new Check parse value.

View File

@ -0,0 +1,33 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Text.Json.Serialization;
namespace PKHeX.Core;
/// <summary>
/// Localization strings for encounter display information.
/// </summary>
public sealed record EncounterDisplayLocalization
{
private static readonly EncounterDisplayLocalizationContext Context = new(LocalizationStorage<EncounterDisplayLocalization>.Options);
public static readonly LocalizationStorage<EncounterDisplayLocalization> Cache = new("encounter", Context.EncounterDisplayLocalization);
public static EncounterDisplayLocalization Get(string language = GameLanguage.DefaultLanguage) => Cache.Get(language);
public static EncounterDisplayLocalization Get(LanguageID language) => Cache.Get(language.GetLanguageCode());
public required string Format { get; set; } = "{0}: {1}";
public required string FormatLevelRange { get; set; } = "{0}: {1}-{2}";
public required string EncounterType { get; set; } = "Encounter Type";
public required string Version { get; set; } = "Version";
public required string Level { get; set; } = "Level";
public required string LevelRange { get; set; } = "Level Range";
public required string Location { get; set; } = "Location";
public required string OriginSeed { get; set; } = "Origin Seed";
public required string PIDType { get; set; } = "PID Type";
public required string Time { get; set; } = "Time";
public required string FrameNewGame { get; set; } = "New Game: 0x{0}, Frame: {1}";
public required string FrameInitial { get; set; } = "Initial: 0x{0}, Frame: {1}";
public required string SuffixDays { get; set; } = " (days: {0})";
}
[JsonSerializable(typeof(EncounterDisplayLocalization))]
public sealed partial class EncounterDisplayLocalizationContext : JsonSerializerContext;

View File

@ -0,0 +1,27 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Text.Json.Serialization;
namespace PKHeX.Core;
/// <summary>
/// Localization strings for general display information.
/// </summary>
public sealed record GeneralLocalization
{
private static readonly GeneralLocalizationContext Context = new(LocalizationStorage<GeneralLocalization>.Options);
public static readonly LocalizationStorage<GeneralLocalization> Cache = new("general", Context.GeneralLocalization);
public static GeneralLocalization Get(string language = GameLanguage.DefaultLanguage) => Cache.Get(language);
public static GeneralLocalization Get(LanguageID language) => Cache.Get(language.GetLanguageCode());
public required string[] StatNames { get; init; }
public required string OriginalTrainer { get; init; } = "Original Trainer";
public required string HandlingTrainer { get; init; } = "Handling Trainer";
public required string GenderMale { get; init; } = "Male";
public required string GenderFemale { get; init; } = "Female";
public required string GenderGenderless { get; init; } = "Genderless";
}
[JsonSerializable(typeof(GeneralLocalization))]
public sealed partial class GeneralLocalizationContext : JsonSerializerContext;

View File

@ -0,0 +1,441 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Text.Json.Serialization;
namespace PKHeX.Core;
/// <summary>
/// Legality Check Message Strings to indicate why certain <see cref="PKM"/> <see cref="LegalInfo"/> values are flagged.
/// </summary>
public sealed class LegalityCheckLocalization
{
private static readonly LegalityCheckLocalizationContext Context = new(LocalizationStorage<LegalityCheckLocalization>.Options);
public static readonly LocalizationStorage<LegalityCheckLocalization> Cache = new("legality", Context.LegalityCheckLocalization);
public static LegalityCheckLocalization Get(string language = GameLanguage.DefaultLanguage) => Cache.Get(language);
public static LegalityCheckLocalization Get(LanguageID language) => Cache.Get(language.GetLanguageCode());
// Message String Name format: L/F[Category][Summary]
#region General Strings
/// <summary>Default text for indicating validity.</summary>
public string Valid { get; set; } = "Valid.";
/// <summary>Default text for indicating legality.</summary>
public string Legal { get; set; } = "Legal!";
/// <summary>Default text for indicating an error has occurred.</summary>
public string Error { get; set; } = "Internal error.";
/// <summary>Analysis not available for the <see cref="PKM"/></summary>
public string AnalysisUnavailable { get; set; } = "Analysis not available for this Pokémon.";
/// <summary>Format text for exporting a legality check result.</summary>
public string F0_1 { get; set; } = "{0}: {1}";
/// <summary>Severity string for <see cref="Severity.Invalid"/></summary>
public string SInvalid { get; set; } = "Invalid";
/// <summary>Severity string for <see cref="Severity.Fishy"/></summary>
public string SFishy { get; set; } = "Fishy";
/// <summary>Severity string for <see cref="Severity.Valid"/></summary>
public string SValid { get; set; } = "Valid";
/// <summary>Severity string for anything not implemented.</summary>
public string NotImplemented { get; set; } = "Not Implemented";
public string AbilityCapsuleUsed { get; set; } = "Ability available with Ability Capsule.";
public string AbilityPatchUsed { get; set; } = "Ability available with Ability Patch.";
public string AbilityPatchRevertUsed { get; set; } = "Ability available with Ability Patch Revert.";
public string AbilityFlag { get; set; } = "Ability matches ability number.";
public string AbilityHiddenFail { get; set; } = "Hidden Ability mismatch for encounter type.";
public string AbilityHiddenUnavailable { get; set; } = "Hidden Ability not available.";
public string AbilityMismatch { get; set; } = "Ability mismatch for encounter.";
public string AbilityMismatch3 { get; set; } = "Ability does not match Generation 3 species ability.";
public string AbilityMismatchFlag { get; set; } = "Ability does not match ability number.";
public string AbilityMismatchGift { get; set; } = "Ability does not match Mystery Gift.";
public string AbilityMismatchPID { get; set; } = "Ability does not match PID.";
public string AbilityUnexpected { get; set; } = "Ability is not valid for species/form.";
public string AwakenedCap { get; set; } = "Individual AV cannot be greater than {0}.";
public string AwakenedShouldBeValue { get; set; } = "{1} AV should be greater than {0}.";
public string BallAbility { get; set; } = "Can't obtain Hidden Ability with Ball.";
public string BallEggCherish { get; set; } = "Can't have Cherish Ball for regular Egg.";
public string BallEggMaster { get; set; } = "Can't have Master Ball for regular Egg.";
public string BallEnc { get; set; } = "Correct ball for encounter type.";
public string BallEncMismatch { get; set; } = "Can't have ball for encounter type.";
public string BallHeavy { get; set; } = "Can't have Heavy Ball for light, low-catch rate species (Gen VII).";
public string BallSpecies { get; set; } = "Can't obtain species in Ball.";
public string BallSpeciesPass { get; set; } = "Ball possible for species.";
public string BallUnavailable { get; set; } = "Ball unobtainable in origin Generation.";
public string ContestZero { get; set; } = "Contest Stats should be 0.";
public string ContestZeroSheen { get; set; } = "Contest Stat Sheen should be 0.";
public string ContestSheenGEQ_0 { get; set; } = "Contest Stat Sheen should be >= {0}.";
public string ContestSheenLEQ_0 { get; set; } = "Contest Stat Sheen should be <= {0}.";
public string DateOutsideConsoleWindow { get; set; } = "Local Date is outside of console's local time window.";
public string DateTimeClockInvalid { get; set; } = "Local Time is not a valid timestamp.";
public string DateOutsideDistributionWindow { get; set; } = "Met Date is outside of distribution window.";
public string EggContest { get; set; } = "Cannot increase Contest Stats of an Egg.";
public string EggEXP { get; set; } = "Eggs cannot receive experience.";
public string EggFMetLevel_0 { get; set; } = "Invalid Met Level, expected {0}.";
public string EggHatchCycles { get; set; } = "Invalid Egg hatch cycles.";
public string EggLocation { get; set; } = "Able to hatch an Egg at Met Location.";
public string EggLocationInvalid { get; set; } = "Can't hatch an Egg at Met Location.";
public string EggLocationNone { get; set; } = "Invalid Egg Location, expected none.";
public string EggLocationPalPark { get; set; } = "Invalid Met Location, expected Pal Park.";
public string EggLocationTrade { get; set; } = "Able to hatch a traded Egg at Met Location.";
public string EggLocationTradeFail { get; set; } = "Invalid Egg Location, shouldn't be 'traded' while an Egg.";
public string EggMetLocationFail { get; set; } = "Can't obtain Egg from Egg Location.";
public string EggNature { get; set; } = "Eggs cannot have their Stat Nature changed.";
public string EggPokeathlon { get; set; } = "Eggs cannot have Pokéathlon stats.";
public string EggPP { get; set; } = "Eggs cannot have modified move PP counts.";
public string EggPPUp { get; set; } = "Cannot apply PP Ups to an Egg.";
public string EggRelearnFlags { get; set; } = "Expected no Relearn Move Flags.";
public string EggShinyLeaf { get; set; } = "Eggs cannot have Shiny Leaf/Crown.";
public string EggShinyPokeStar { get; set; } = "Eggs cannot be a Pokéstar Studios star.";
public string EggSpecies { get; set; } = "Can't obtain Egg for this species.";
public string EggUnhatched { get; set; } = "Valid un-hatched Egg.";
public string EncCondition { get; set; } = "Valid Wild Encounter at location.";
public string EncConditionBadRNGFrame { get; set; } = "Unable to match encounter conditions to a possible RNG frame.";
public string EncConditionBadSpecies { get; set; } = "Species does not exist in origin game.";
public string EncGift { get; set; } = "Unable to match a gift Egg encounter from origin game.";
public string EncGiftEggEvent { get; set; } = "Unable to match an event Egg encounter from origin game.";
public string EncGiftIVMismatch { get; set; } = "IVs do not match Mystery Gift Data.";
public string EncGiftNicknamed { get; set; } = "Event gift has been nicknamed.";
public string EncGiftNotFound { get; set; } = "Unable to match to a Mystery Gift in the database.";
public string EncGiftPIDMismatch { get; set; } = "Mystery Gift fixed PID mismatch.";
public string EncGiftShinyMismatch { get; set; } = "Mystery Gift shiny mismatch.";
public string EncGiftVersionNotDistributed { get; set; } = "Mystery Gift cannot be received by this version.";
public string EncInvalid { get; set; } = "Unable to match an encounter from origin game.";
public string EncMasteryInitial { get; set; } = "Initial move mastery flags do not match the encounter's expected state.";
public string EncTradeChangedNickname { get; set; } = "In-game Trade Nickname has been altered.";
public string EncTradeChangedOT { get; set; } = "In-game Trade OT has been altered.";
public string EncTradeIndexBad { get; set; } = "In-game Trade invalid index?";
public string EncTradeMatch { get; set; } = "Valid In-game trade.";
public string EncTradeUnchanged { get; set; } = "In-game Trade OT and Nickname have not been altered.";
public string EncStaticPIDShiny { get; set; } = "Encounter shiny mismatch.";
public string EncTypeMatch { get; set; } = "Encounter Type matches encounter.";
public string EncTypeMismatch { get; set; } = "Encounter Type does not match encounter.";
public string EncUnreleased { get; set; } = "Unreleased event.";
public string EncUnreleasedEMewJP { get; set; } = "Non japanese Mew from Faraway Island. Unreleased event.";
public string EReaderAmerica { get; set; } = "American E-Reader Berry in Japanese save file.";
public string EReaderInvalid { get; set; } = "Invalid E-Reader Berry.";
public string EReaderJapan { get; set; } = "Japanese E-Reader Berry in international save file.";
public string Effort2Remaining { get; set; } = "2 EVs remaining.";
public string EffortAbove252 { get; set; } = "EVs cannot go above 252.";
public string EffortAbove510 { get; set; } = "EV total cannot be above 510.";
public string EffortAllEqual { get; set; } = "EVs are all equal.";
public string EffortCap100 { get; set; } = "Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100.";
public string EffortEgg { get; set; } = "Eggs cannot receive EVs.";
public string EffortShouldBeZero { get; set; } = "Cannot receive EVs.";
public string EffortEXPIncreased { get; set; } = "All EVs are zero, but leveled above Met Level.";
public string EffortUntrainedCap { get; set; } = "Individual EV without changing EXP cannot be greater than {0}.";
public string EvoInvalid { get; set; } = "Evolution not valid (or level/trade evolution unsatisfied).";
public string EvoTradeReqOutsider { get; set; } = "Outsider {0} should have evolved into {1}.";
public string EvoTradeRequired { get; set; } = "Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.";
public string FatefulGiftMissing { get; set; } = "Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?";
public string FatefulInvalid { get; set; } = "Fateful Encounter should not be checked.";
public string FatefulMissing { get; set; } = "Special In-game Fateful Encounter flag missing.";
public string FatefulMystery { get; set; } = "Mystery Gift Fateful Encounter.";
public string FatefulMysteryMissing { get; set; } = "Mystery Gift Fateful Encounter flag missing.";
public string FavoriteMarkingUnavailable { get; set; } = "Favorite Marking is not available.";
public string FormArgumentLEQ_0 { get; set; } = "Form argument is too high for current form.";
public string FormArgumentGEQ_0 { get; set; } = "Form argument is too low for current form.";
public string FormArgumentNotAllowed { get; set; } = "Form argument is not allowed for this encounter.";
public string FormArgumentValid { get; set; } = "Form argument is valid.";
public string FormArgumentInvalid { get; set; } = "Form argument is not valid.";
public string FormBattle { get; set; } = "Form cannot exist outside of a battle.";
public string FormEternal { get; set; } = "Valid Eternal Flower encounter.";
public string FormEternalInvalid { get; set; } = "Invalid Eternal Flower encounter.";
public string FormInvalidGame { get; set; } = "Form cannot be obtained in origin game.";
public string FormInvalidNature { get; set; } = "Form cannot have this nature.";
public string FormInvalidRange { get; set; } = "Form Count is out of range. Expected <= {0}, got {1}.";
public string FormItem { get; set; } = "Held item matches Form.";
public string FormItemInvalid { get; set; } = "Held item does not match Form.";
public string FormParty { get; set; } = "Form cannot exist outside of Party.";
public string FormPikachuCosplay { get; set; } = "Only Cosplay Pikachu can have this form.";
public string FormPikachuCosplayInvalid { get; set; } = "Cosplay Pikachu cannot have the default form.";
public string FormPikachuEventInvalid { get; set; } = "Event Pikachu cannot have the default form.";
public string FormInvalidExpect_0 { get; set; } = "Form is invalid, expected form index {0}.";
public string FormValid { get; set; } = "Form is Valid.";
public string FormVivillon { get; set; } = "Valid Vivillon pattern.";
public string FormVivillonEventPre { get; set; } = "Event Vivillon pattern on pre-evolution.";
public string FormVivillonInvalid { get; set; } = "Invalid Vivillon pattern.";
public string FormVivillonNonNative { get; set; } = "Non-native Vivillon pattern.";
public string G1CatchRateChain { get; set; } = "Catch rate does not match any species from Pokémon evolution chain.";
public string G1CatchRateEvo { get; set; } = "Catch rate match species without encounters. Expected a preevolution catch rate.";
public string G1CatchRateItem { get; set; } = "Catch rate does not match a valid held item from Generation 2.";
public string G1CatchRateMatchPrevious { get; set; } = "Catch Rate matches a species from Pokémon evolution chain.";
public string G1CatchRateMatchTradeback { get; set; } = "Catch rate matches a valid held item from Generation 2.";
public string G1CatchRateNone { get; set; } = "Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items.";
public string G1CharNick { get; set; } = "Nickname from Generation 1/2 uses unavailable characters.";
public string G1CharOT { get; set; } = "OT from Generation 1/2 uses unavailable characters.";
public string G1OTGender { get; set; } = "Female OT from Generation 1/2 is invalid.";
public string G1Stadium { get; set; } = "Incorrect Stadium OT.";
public string G1Type1Fail { get; set; } = "Invalid Type A, does not match species type.";
public string G1Type2Fail { get; set; } = "Invalid Type B, does not match species type.";
public string G1TypeMatch1 { get; set; } = "Valid Type A, matches species type.";
public string G1TypeMatch2 { get; set; } = "Valid Type B, matches species type.";
public string G1TypeMatchPorygon { get; set; } = "Porygon with valid Type A and B values.";
public string G1TypePorygonFail { get; set; } = "Porygon with invalid Type A and B values. Does not a match a valid type combination.";
public string G1TypePorygonFail1 { get; set; } = "Porygon with invalid Type A value.";
public string G1TypePorygonFail2 { get; set; } = "Porygon with invalid Type B value.";
public string G2InvalidTileTreeNotFound { get; set; } = "Could not find a tree for Crystal headbutt encounter that matches OTID.";
public string G2TreeID { get; set; } = "Found a tree for Crystal headbutt encounter that matches OTID.";
public string G2OTGender { get; set; } = "OT from Virtual Console games other than Crystal cannot be female.";
public string G3EReader { get; set; } = "Non Japanese Shadow E-reader Pokémon. Unreleased encounter.";
public string G3OTGender { get; set; } = "OT from Colosseum/XD cannot be female.";
public string G4InvalidTileR45Surf { get; set; } = "Johto Route 45 surfing encounter. Unreachable Water tiles.";
public string G5IVAll30 { get; set; } = "All IVs of N's Pokémon should be 30.";
public string G5PIDShinyGrotto { get; set; } = "Hidden Grotto captures cannot be shiny.";
public string G5SparkleInvalid { get; set; } = "Special In-game N's Sparkle flag should not be checked.";
public string G5SparkleRequired { get; set; } = "Special In-game N's Sparkle flag missing.";
public string GanbaruStatTooHigh { get; set; } = "One or more Ganbaru Value is above the natural limit of (10 - IV bonus).";
public string GenderInvalidNone { get; set; } = "Genderless Pokémon should not have a gender.";
public string GeoBadOrder { get; set; } = "GeoLocation Memory: Gap/Blank present.";
public string GeoHardwareInvalid { get; set; } = "Geolocation: Country is not in 3DS region.";
public string GeoHardwareRange { get; set; } = "Invalid Console Region.";
public string GeoHardwareValid { get; set; } = "Geolocation: Country is in 3DS region.";
public string GeoMemoryMissing { get; set; } = "GeoLocation Memory: Memories should be present.";
public string GeoNoCountryHT { get; set; } = "GeoLocation Memory: HT Name present but has no previous Country.";
public string GeoNoRegion { get; set; } = "GeoLocation Memory: Region without Country.";
public string HyperTrainLevelGEQ_0 { get; set; } = "Can't Hyper Train a Pokémon that isn't level {0}.";
public string HyperPerfectAll { get; set; } = "Can't Hyper Train a Pokémon with perfect IVs.";
public string HyperPerfectOne { get; set; } = "Can't Hyper Train a perfect IV.";
public string HyperPerfectUnavailable { get; set; } = "Can't Hyper Train any IV(s).";
public string ItemEgg { get; set; } = "Eggs cannot hold items.";
public string ItemUnreleased { get; set; } = "Held item is unreleased.";
public string IVAllEqual_0 { get; set; } = "All IVs are {0}.";
public string IVNotCorrect { get; set; } = "IVs do not match encounter requirements.";
public string IVFlawlessCountGEQ_0 { get; set; } = "Should have at least {0} IVs = 31.";
public string LevelEXPThreshold { get; set; } = "Current experience matches level threshold.";
public string LevelEXPTooHigh { get; set; } = "Current experience exceeds maximum amount for level 100.";
public string LevelMetBelow { get; set; } = "Current level is below met level.";
public string LevelMetGift { get; set; } = "Met Level does not match Mystery Gift level.";
public string LevelMetGiftFail { get; set; } = "Current Level below Mystery Gift level.";
public string LevelMetSane { get; set; } = "Current level is not below met level.";
public string MarkValueOutOfRange_0 { get; set; } = "Individual marking at index {0} is not within the allowed value range.";
public string MarkValueShouldBeZero { get; set; } = "Marking flags cannot be set.";
public string MarkValueUnusedBitsPresent { get; set; } = "Marking flags uses bits beyond the accessible range.";
public string MemoryArgBadCatch_H { get; set; } = "{0} Memory: {0} did not catch this.";
public string MemoryArgBadHatch_H { get; set; } = "{0} Memory: {0} did not hatch this.";
public string MemoryArgBadHT { get; set; } = "Memory: Can't have Handling Trainer Memory as Egg.";
public string MemoryArgBadID_H { get; set; } = "{0} Memory: Can't obtain Memory on {0} Version.";
public string MemoryArgBadItem_H1 { get; set; } = "{0} Memory: Species can't hold this item.";
public string MemoryArgBadLocation_H { get; set; } = "{0} Memory: Can't obtain Location on {0} Version.";
public string MemoryArgBadMove_H1 { get; set; } = "{0} Memory: Species can't learn {1}.";
public string MemoryArgBadOTEgg_H { get; set; } = "{0} Memory: Link Trade is not a valid first memory.";
public string MemoryArgBadSpecies_H1 { get; set; } = "{0} Memory: Can't capture species in game.";
public string MemoryArgSpecies_H { get; set; } = "{0} Memory: Species can be captured in game.";
public string MemoryCleared_H { get; set; } = "Memory: Not cleared properly.";
public string MemoryValid_H { get; set; } = "{0} Memory is valid.";
public string MemoryFeelInvalid_H { get; set; } = "{0} Memory: Invalid Feeling.";
public string MemoryHTFlagInvalid { get; set; } = "Untraded: Current handler should not be the Handling Trainer.";
public string MemoryHTGender_0 { get; set; } = "HT Gender invalid: {0}";
public string MemoryHTLanguage { get; set; } = "HT Language is missing.";
public string MemoryIndexArgHT { get; set; } = "Should have a HT Memory TextVar value (somewhere).";
public string MemoryIndexFeel_H1 { get; set; } = "{0} Memory: Feeling should be index {1}.";
public string MemoryIndexFeelHTLEQ9 { get; set; } = "Should have a HT Memory Feeling value 0-9.";
public string MemoryIndexID_H1 { get; set; } = "{0} Memory: Should be index {1}.";
public string MemoryIndexIntensity_H1 { get; set; } = "{0} Memory: Intensity should be index {1}.";
public string MemoryIndexIntensityHT1 { get; set; } = "Should have a HT Memory Intensity value (1st).";
public string MemoryIndexIntensityMin_H1 { get; set; } = "{0} Memory: Intensity should be at least {1}.";
public string MemoryIndexLinkHT { get; set; } = "Should have a Link Trade HT Memory.";
public string MemoryIndexVar { get; set; } = "{0} Memory: TextVar should be index {1}.";
public string MemoryMissingHT { get; set; } = "Memory: Handling Trainer Memory missing.";
public string MemoryMissingOT { get; set; } = "Memory: Original Trainer Memory missing.";
public string MemorySocialZero { get; set; } = "Social Stat should be zero.";
public string MemoryStatSocialLEQ_0 { get; set; } = "Social Stat should be <= {0}";
public string MemoryStatAffectionHT0 { get; set; } = "Untraded: Handling Trainer Affection should be 0.";
public string MemoryStatAffectionOT0 { get; set; } = "OT Affection should be 0.";
public string MemoryStatFriendshipHT0 { get; set; } = "Untraded: Handling Trainer Friendship should be 0.";
public string MemoryStatFriendshipOTBaseEvent_0 { get; set; } = "Event OT Friendship does not match base friendship ({0}).";
public string MetDetailTimeOfDay { get; set; } = "Met Time of Day value is not within the expected range.";
public string MoveEvoFCombination_0 { get; set; } = "Moves combinations is not compatible with {0} evolution.";
public string MoveFExpectSingle_0 { get; set; } = "Expected: {0}";
public string MoveKeldeoMismatch { get; set; } = "Keldeo Move/Form mismatch.";
public string MovePPExpectHealed_0 { get; set; } = "Move {0} PP is below the amount expected.";
public string MovePPTooHigh_0 { get; set; } = "Move {0} PP is above the amount allowed.";
public string MovePPUpsTooHigh_0 { get; set; } = "Move {0} PP Ups is above the amount allowed.";
public string MoveShopAlphaMoveShouldBeMastered_0 { get; set; } = "Alpha Move should be marked as mastered.";
public string MoveShopAlphaMoveShouldBeOther { get; set; } = "Alpha encounter cannot be found with this Alpha Move.";
public string MoveShopAlphaMoveShouldBeZero { get; set; } = "Only Alphas may have an Alpha Move set.";
public string MoveShopMasterInvalid_0 { get; set; } = "Cannot manually master {0}: not permitted to master.";
public string MoveShopMasterNotLearned_0 { get; set; } = "Cannot manually master {0}: not in possible learned level up moves.";
public string MoveShopPurchaseInvalid_0 { get; set; } = "Cannot purchase {0} from the move shop.";
public string MoveTechRecordFlagMissing_0 { get; set; } = "Unexpected Technical Record Learned flag: {0}";
public string NickFlagEggNo { get; set; } = "Egg must be not nicknamed.";
public string NickFlagEggYes { get; set; } = "Egg must be nicknamed.";
public string NickInvalidChar { get; set; } = "Cannot be given this Nickname.";
public string NickLengthLong { get; set; } = "Nickname too long.";
public string NickLengthShort { get; set; } = "Nickname is empty.";
public string NickMatchLanguage { get; set; } = "Nickname matches species name.";
public string NickMatchLanguageEgg { get; set; } = "Egg matches language Egg name.";
public string NickMatchLanguageEggFail { get; set; } = "Egg name does not match language Egg name.";
public string NickMatchLanguageFail { get; set; } = "Nickname does not match species name.";
public string NickMatchLanguageFlag { get; set; } = "Nickname flagged, matches species name.";
public string NickMatchNoOthers { get; set; } = "Nickname does not match another species name.";
public string NickMatchNoOthersFail { get; set; } = "Nickname matches another species name (+language).";
public string OTLanguage { get; set; } = "Language ID should be {0}, not {1}.";
public string OTLong { get; set; } = "OT Name too long.";
public string OTShort { get; set; } = "OT Name too short.";
public string OTSuspicious { get; set; } = "Suspicious Original Trainer details.";
public string OT_IDEqual { get; set; } = "TID16 and SID16 are equal.";
public string OT_IDs0 { get; set; } = "TID16 and SID16 are 0.";
public string OT_SID0 { get; set; } = "SID16 is zero.";
public string OT_SID0Invalid { get; set; } = "SID16 should be 0.";
public string OT_TID0 { get; set; } = "TID16 is zero.";
public string OT_IDInvalid { get; set; } = "TID16 and SID16 combination is not possible.";
public string PIDEncryptWurmple { get; set; } = "Wurmple evolution Encryption Constant mismatch.";
public string PIDEncryptZero { get; set; } = "Encryption Constant is not set.";
public string PIDEqualsEC { get; set; } = "Encryption Constant matches PID.";
public string PIDGenderMatch { get; set; } = "Gender matches PID.";
public string PIDGenderMismatch { get; set; } = "PID-Gender mismatch.";
public string PIDNatureMatch { get; set; } = "Nature matches PID.";
public string PIDNatureMismatch { get; set; } = "PID-Nature mismatch.";
public string PIDTypeMismatch { get; set; } = "PID+ correlation does not match what was expected for the Encounter's type.";
public string PIDZero { get; set; } = "PID is not set.";
public string PokerusDaysTooHigh_0 { get; set; } = "Pokérus Days Remaining value is too high; expected <= {0}.";
public string PokerusStrainUnobtainable_0 { get; set; } = "Pokérus Strain {0} cannot be obtained.";
public string RibbonAllValid { get; set; } = "All ribbons accounted for.";
public string RibbonEgg { get; set; } = "Can't receive Ribbon(s) as an Egg.";
public string RibbonFInvalid_0 { get; set; } = "Invalid Ribbons: {0}";
public string RibbonMissing_0 { get; set; } = "Missing Ribbons: {0}";
public string RibbonMarkingInvalid_0 { get; set; } = "Invalid Marking: {0}";
public string RibbonMarkingAffixed_0 { get; set; } = "Invalid Affixed Ribbon/Marking: {0}";
public string StatDynamaxInvalid { get; set; } = "Dynamax Level is not within the expected range.";
public string StatIncorrectHeight { get; set; } = "Calculated Height does not match stored value.";
public string StatIncorrectHeightCopy { get; set; } = "Copy Height does not match the original value.";
public string StatIncorrectHeightValue { get; set; } = "Height does not match the expected value.";
public string StatIncorrectWeight { get; set; } = "Calculated Weight does not match stored value.";
public string StatIncorrectWeightValue { get; set; } = "Weight does not match the expected value.";
public string StatInvalidHeightWeight { get; set; } = "Height / Weight values are statistically improbable.";
public string StatIncorrectCP { get; set; } = "Calculated CP does not match stored value.";
public string StatGigantamaxInvalid { get; set; } = "Gigantamax Flag mismatch.";
public string StatGigantamaxValid { get; set; } = "Gigantamax Flag was changed via Max Soup.";
public string StatNatureInvalid { get; set; } = "Stat Nature is not within the expected range.";
public string StatBattleVersionInvalid { get; set; } = "Battle Version is not within the expected range.";
public string StatNobleInvalid { get; set; } = "Noble Flag mismatch.";
public string StatAlphaInvalid { get; set; } = "Alpha Flag mismatch.";
public string StoredSourceEgg { get; set; } = "Egg must be in Box or Party.";
public string StoredSlotSourceInvalid_0 { get; set; } = "Invalid Stored Source: {0}";
public string SuperComplete { get; set; } = "Super Training complete flag mismatch.";
public string SuperDistro { get; set; } = "Distribution Super Training missions are not released.";
public string SuperEgg { get; set; } = "Can't Super Train an Egg.";
public string SuperNoComplete { get; set; } = "Can't have active Super Training complete flag for origins.";
public string SuperNoUnlocked { get; set; } = "Can't have active Super Training unlocked flag for origins.";
public string SuperUnavailable { get; set; } = "Super Training missions are not available in games visited.";
public string SuperUnused { get; set; } = "Unused Super Training Flag is flagged.";
public string TeraTypeIncorrect { get; set; } = "Tera Type does not match the expected value.";
public string TeraTypeMismatch { get; set; } = "Tera Type does not match either of the default types.";
public string TradeNotAvailable { get; set; } = "Encounter cannot be traded to the active trainer.";
public string TrainerIDNoSeed { get; set; } = "Trainer ID is not obtainable from any RNG seed.";
public string TransferBad { get; set; } = "Incorrectly transferred from previous generation.";
public string TransferCurrentHandlerInvalid { get; set; } = "Invalid Current handler value, trainer details for save file expected another value.";
public string TransferEgg { get; set; } = "Can't transfer Eggs between Generations.";
public string TransferEggLocationTransporter { get; set; } = "Invalid Met Location, expected Poké Transfer.";
public string TransferEggMetLevel { get; set; } = "Invalid Met Level for transfer.";
public string TransferEggVersion { get; set; } = "Can't transfer Eggs to this game.";
public string TransferFlagIllegal { get; set; } = "Flagged as illegal by the game (glitch abuse).";
public string TransferHTFlagRequired { get; set; } = "Current handler cannot be the OT.";
public string TransferHTMismatchName { get; set; } = "Handling trainer does not match the expected trainer name.";
public string TransferHTMismatchGender { get; set; } = "Handling trainer does not match the expected trainer gender.";
public string TransferHTMismatchLanguage { get; set; } = "Handling trainer does not match the expected trainer language.";
public string TransferKoreanGen4 { get; set; } = "Korean Generation 4 games cannot interact with International Generation 4 games.";
public string TransferMet { get; set; } = "Invalid Met Location, expected Poké Transfer or Crown.";
public string TransferNotPossible { get; set; } = "Unable to transfer into current format from origin format.";
public string TransferMetLocation { get; set; } = "Invalid Transfer Met Location.";
public string TransferNature { get; set; } = "Invalid Nature for transfer Experience.";
public string TransferObedienceLevel { get; set; } = "Invalid Obedience Level.";
public string TransferPIDECBitFlip { get; set; } = "PID should be equal to EC [with top bit flipped]!";
public string TransferPIDECEquals { get; set; } = "PID should be equal to EC!";
public string TransferPIDECXor { get; set; } = "Encryption Constant matches shinyxored PID.";
public string TransferTrackerMissing { get; set; } = "Pokémon HOME Transfer Tracker is missing.";
public string TransferTrackerShouldBeZero { get; set; } = "Pokémon HOME Transfer Tracker should be 0.";
public string TrashBytesExpected { get; set; } = "Expected Trash Bytes.";
public string TrashBytesMismatchInitial { get; set; } = "Expected initial trash bytes to match the encounter.";
public string TrashBytesMissingTerminator { get; set; } = "Final terminator missing.";
public string TrashBytesShouldBeEmpty { get; set; } = "Trash Bytes should be cleared.";
#endregion
public string EncTradeShouldHaveEvolvedToSpecies_0 { get; set; } = "Trade Encounter should have evolved to species: {0}.";
public string EncGiftLanguageNotDistributed { get; set; } = "Gift Encounter was never distributed with this language.";
public string EncGiftRegionNotDistributed { get; set; } = "Gift Encounter was never distributed to this Console Region.";
public string FormInvalidRangeLEQ_0 { get; set; } = "Form Count is out of range. Expected <= {0}, got {1}.";
public string MovesShouldMatchRelearnMoves { get; set; } = "Moves should exactly match Relearn Moves.";
public string MemoryStatEnjoyment_0 { get; set; } = "Enjoyment should be {0}.";
public string MemoryStatFullness_0 { get; set; } = "Fullness should be {0}.";
public string MemoryStatFullnessLEQ_0 { get; set; } = "Fullness should be <= {0}.";
public string OTLanguageShouldBe_0 { get; set; } = "Language ID should be {0}, not {1}.";
public string OTLanguageShouldBe_0or1 { get; set; } = "Language ID should be {0} or {1}, not {2}.";
public string OTLanguageShouldBeLeq_0 { get; set; } = "Language ID should be <= {0}, not {1}.";
public string OTLanguageCannotPlayOnVersion_0 { get; set; } = "Language ID {0} cannot be played on this version.";
public string OTLanguageCannotTransferToConsoleRegion_0 { get; set; } = "Language ID {0} cannot be transferred to this Console Region.";
public string WordFilterInvalidCharacter_0 { get; set; } = "Word Filter: Invalid character '{0}' (0x{1}).";
public string WordFilterFlaggedPattern_01 { get; set; } = "Word Filter ({1}): Flagged pattern '{0}'.";
public string WordFilterTooManyNumbers_0 { get; set; } = "Word Filter: Too many numbers (>{0}).";
public string BulkCloneDetectedDetails { get; set; } = "Clone detected (Details).";
public string BulkCloneDetectedTracker { get; set; } = "Clone detected (Duplicate Tracker).";
public string HintEvolvesToSpecies_0 { get; set; } = "Evolves to species: {0}.";
public string HintEvolvesToRareForm_0 { get; set; } = "Evolves to rare form: {0}.";
public string BulkSharingEncryptionConstantGenerationDifferent { get; set; } = "Detected sharing of Encryption Constant across generations.";
public string BulkSharingEncryptionConstantGenerationSame { get; set; } = "Detected sharing of Encryption Constant.";
public string BulkSharingEncryptionConstantRNGType { get; set; } = "Detected sharing of Encryption Constant sharing for different RNG encounters.";
public string BulkSharingPIDGenerationDifferent { get; set; } = "Detected sharing of PID across generations.";
public string BulkSharingPIDGenerationSame { get; set; } = "Detected sharing of PID.";
public string BulkSharingPIDRNGType { get; set; } = "Detected sharing of PID for different RNG encounters.";
public string BulkDuplicateMysteryGiftEggReceived { get; set; } = "Detected multiple redemptions of the same non-repeatable Mystery Gift Egg.";
public string BulkSharingTrainerID { get; set; } = "Detected sharing of Trainer ID across multiple trainer names.";
public string BulkSharingTrainerVersion { get; set; } = "Detected sharing of Trainer ID across multiple versions.";
}
[JsonSerializable(typeof(LegalityCheckLocalization))]
internal sealed partial class LegalityCheckLocalizationContext : JsonSerializerContext;

View File

@ -0,0 +1,407 @@
using System;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
/// <summary>
/// Provides extension methods for <see cref="LegalityCheckResultCode"/> to convert to human-readable strings.
/// </summary>
public static class LegalityCheckResultCodeExtensions
{
public static bool IsArgument(this LegalityCheckResultCode code) => code is < FirstWithMove and >= FirstWithArgument;
public static bool IsMove(this LegalityCheckResultCode code) => code is < FirstWithLanguage and >= FirstWithMove;
public static bool IsLanguage(this LegalityCheckResultCode code) => code is < FirstWithMemory and >= FirstWithLanguage;
public static bool IsMemory(this LegalityCheckResultCode code) => code is < FirstComplex and >= FirstWithMemory;
/// <summary>
/// Returns the template string for the given result code.
/// </summary>
public static string GetTemplate(this LegalityCheckResultCode code, LegalityCheckLocalization localization) => code switch
{
// General Strings
Valid => localization.Valid,
Error => localization.Error,
// Ability
AbilityCapsuleUsed => localization.AbilityCapsuleUsed,
AbilityPatchUsed => localization.AbilityPatchUsed,
AbilityPatchRevertUsed => localization.AbilityPatchRevertUsed,
AbilityFlag => localization.AbilityFlag,
AbilityHiddenFail => localization.AbilityHiddenFail,
AbilityHiddenUnavailable => localization.AbilityHiddenUnavailable,
AbilityMismatch => localization.AbilityMismatch,
AbilityMismatch3 => localization.AbilityMismatch3,
AbilityMismatchFlag => localization.AbilityMismatchFlag,
AbilityMismatchGift => localization.AbilityMismatchGift,
AbilityMismatchPID => localization.AbilityMismatchPID,
AbilityUnexpected => localization.AbilityUnexpected,
// Awakened Values
AwakenedCap => localization.AwakenedCap,
AwakenedStatGEQ_01 => localization.AwakenedShouldBeValue,
// Ball
BallAbility => localization.BallAbility,
BallEggCherish => localization.BallEggCherish,
BallEggMaster => localization.BallEggMaster,
BallEnc => localization.BallEnc,
BallEncMismatch => localization.BallEncMismatch,
BallHeavy => localization.BallHeavy,
BallSpecies => localization.BallSpecies,
BallSpeciesPass => localization.BallSpeciesPass,
BallUnavailable => localization.BallUnavailable,
// Contest
ContestZero => localization.ContestZero,
ContestZeroSheen => localization.ContestZeroSheen,
ContestSheenGEQ_0 => localization.ContestSheenGEQ_0,
ContestSheenLEQ_0 => localization.ContestSheenLEQ_0,
// Date & Timestamps
DateOutsideConsoleWindow => localization.DateOutsideConsoleWindow,
DateTimeClockInvalid => localization.DateTimeClockInvalid,
DateOutsideDistributionWindow => localization.DateOutsideDistributionWindow,
// Egg
EggContest => localization.EggContest,
EggEXP => localization.EggEXP,
EggFMetLevel_0 => localization.EggFMetLevel_0,
EggHatchCycles => localization.EggHatchCycles,
EggLocation => localization.EggLocation,
EggLocationInvalid => localization.EggLocationInvalid,
EggLocationNone => localization.EggLocationNone,
EggLocationPalPark => localization.EggLocationPalPark,
EggLocationTrade => localization.EggLocationTrade,
EggLocationTradeFail => localization.EggLocationTradeFail,
EggMetLocationFail => localization.EggMetLocationFail,
EggNature => localization.EggNature,
EggPokeathlon => localization.EggPokeathlon,
EggPP => localization.EggPP,
EggPPUp => localization.EggPPUp,
EggRelearnFlags => localization.EggRelearnFlags,
EggShinyLeaf => localization.EggShinyLeaf,
EggShinyPokeStar => localization.EggShinyPokeStar,
EggSpecies => localization.EggSpecies,
EggUnhatched => localization.EggUnhatched,
// Encounter
EncCondition => localization.EncCondition,
EncConditionBadRNGFrame => localization.EncConditionBadRNGFrame,
EncConditionBadSpecies => localization.EncConditionBadSpecies,
EncGift => localization.EncGift,
EncGiftEggEvent => localization.EncGiftEggEvent,
EncGiftIVMismatch => localization.EncGiftIVMismatch,
EncGiftNicknamed => localization.EncGiftNicknamed,
EncGiftNotFound => localization.EncGiftNotFound,
EncGiftPIDMismatch => localization.EncGiftPIDMismatch,
EncGiftShinyMismatch => localization.EncGiftShinyMismatch,
EncGiftVersionNotDistributed => localization.EncGiftVersionNotDistributed,
EncInvalid => localization.EncInvalid,
EncMasteryInitial => localization.EncMasteryInitial,
EncTradeChangedNickname => localization.EncTradeChangedNickname,
EncTradeChangedOT => localization.EncTradeChangedOT,
EncTradeIndexBad => localization.EncTradeIndexBad,
EncTradeMatch => localization.EncTradeMatch,
EncTradeUnchanged => localization.EncTradeUnchanged,
EncStaticPIDShiny => localization.EncStaticPIDShiny,
EncTypeMatch => localization.EncTypeMatch,
EncTypeMismatch => localization.EncTypeMismatch,
EncUnreleased => localization.EncUnreleased,
EncUnreleasedEMewJP => localization.EncUnreleasedEMewJP,
// E-Reader
EReaderAmerica => localization.EReaderAmerica,
EReaderInvalid => localization.EReaderInvalid,
EReaderJapan => localization.EReaderJapan,
// Effort Values
Effort2Remaining => localization.Effort2Remaining,
EffortAbove252 => localization.EffortAbove252,
EffortAbove510 => localization.EffortAbove510,
EffortAllEqual => localization.EffortAllEqual,
EffortCap100 => localization.EffortCap100,
EffortEgg => localization.EffortEgg,
EffortShouldBeZero => localization.EffortShouldBeZero,
EffortEXPIncreased => localization.EffortEXPIncreased,
EffortUntrainedCap_0 => localization.EffortUntrainedCap,
// Evolution
EvoInvalid => localization.EvoInvalid,
EvoTradeReqOutsider_0 => localization.EvoTradeReqOutsider,
EvoTradeRequired => localization.EvoTradeRequired,
// Form
FormArgumentLEQ_0 => localization.FormArgumentLEQ_0,
FormArgumentGEQ_0 => localization.FormArgumentGEQ_0,
FormArgumentNotAllowed => localization.FormArgumentNotAllowed,
FormArgumentValid => localization.FormArgumentValid,
FormArgumentInvalid => localization.FormArgumentInvalid,
FormBattle => localization.FormBattle,
FormEternal => localization.FormEternal,
FormEternalInvalid => localization.FormEternalInvalid,
FormInvalidGame => localization.FormInvalidGame,
FormInvalidNature => localization.FormInvalidNature,
FormInvalidRange_0 => localization.FormInvalidRange,
FormItemMatches => localization.FormItem,
FormItemInvalid => localization.FormItemInvalid,
FormParty => localization.FormParty,
FormPikachuCosplay => localization.FormPikachuCosplay,
FormPikachuCosplayInvalid => localization.FormPikachuCosplayInvalid,
FormPikachuEventInvalid => localization.FormPikachuEventInvalid,
FormInvalidExpect_0 => localization.FormInvalidExpect_0,
FormValid => localization.FormValid,
FormVivillon => localization.FormVivillon,
FormVivillonEventPre => localization.FormVivillonEventPre,
FormVivillonInvalid => localization.FormVivillonInvalid,
FormVivillonNonNative => localization.FormVivillonNonNative,
// Hyper Training
HyperTrainLevelGEQ_0 => localization.HyperTrainLevelGEQ_0,
HyperPerfectAll => localization.HyperPerfectAll,
HyperPerfectOne => localization.HyperPerfectOne,
HyperPerfectUnavailable => localization.HyperPerfectUnavailable,
// IVs
IVAllEqual_0 => localization.IVAllEqual_0,
IVNotCorrect => localization.IVNotCorrect,
IVFlawlessCountGEQ_0 => localization.IVFlawlessCountGEQ_0,
// Markings
MarkValueOutOfRange_0 => localization.MarkValueOutOfRange_0,
MarkValueShouldBeZero => localization.MarkValueShouldBeZero,
MarkValueUnusedBitsPresent => localization.MarkValueUnusedBitsPresent,
// Moves
MoveEvoFCombination_0 => localization.MoveEvoFCombination_0,
MovePPExpectHealed_0 => localization.MovePPExpectHealed_0,
MovePPTooHigh_0 => localization.MovePPTooHigh_0,
MovePPUpsTooHigh_0 => localization.MovePPUpsTooHigh_0,
MoveShopMasterInvalid_0 => localization.MoveShopMasterInvalid_0,
MoveShopMasterNotLearned_0 => localization.MoveShopMasterNotLearned_0,
MoveShopPurchaseInvalid_0 => localization.MoveShopPurchaseInvalid_0,
MoveTechRecordFlagMissing_0 => localization.MoveTechRecordFlagMissing_0,
// Memory
MemoryStatSocialLEQ_0 => localization.MemoryStatSocialLEQ_0,
// Pokerus
PokerusDaysLEQ_0 => localization.PokerusDaysTooHigh_0,
PokerusStrainUnobtainable_0 => localization.PokerusStrainUnobtainable_0,
// Ribbons
RibbonFInvalid_0 => localization.RibbonFInvalid_0,
RibbonMissing_0 => localization.RibbonMissing_0,
RibbonMarkingInvalid_0 => localization.RibbonMarkingInvalid_0,
RibbonMarkingAffixed_0 => localization.RibbonMarkingAffixed_0,
// Storage
StoredSlotSourceInvalid_0 => localization.StoredSlotSourceInvalid_0,
EncGiftLanguageNotDistributed_0 => localization.EncGiftLanguageNotDistributed,
EncGiftRegionNotDistributed => localization.EncGiftRegionNotDistributed,
EncTradeShouldHaveEvolvedToSpecies_0 => localization.EncTradeShouldHaveEvolvedToSpecies_0,
FatefulGiftMissing => localization.FatefulGiftMissing,
FatefulInvalid => localization.FatefulInvalid,
FatefulMissing => localization.FatefulMissing,
FatefulMystery => localization.FatefulMystery,
FatefulMysteryMissing => localization.FatefulMysteryMissing,
FavoriteMarkingUnavailable => localization.FavoriteMarkingUnavailable,
FormInvalidRangeLEQ_0 => localization.FormInvalidRangeLEQ_0,
G1CatchRateChain => localization.G1CatchRateChain,
G1CatchRateEvo => localization.G1CatchRateEvo,
G1CatchRateItem => localization.G1CatchRateItem,
G1CatchRateMatchPrevious => localization.G1CatchRateMatchPrevious,
G1CatchRateMatchTradeback => localization.G1CatchRateMatchTradeback,
G1CatchRateNone => localization.G1CatchRateNone,
G1CharNick => localization.G1CharNick,
G1CharOT => localization.G1CharOT,
G1OTGender => localization.G1OTGender,
G1Stadium => localization.G1Stadium,
G1Type1Fail => localization.G1Type1Fail,
G1Type2Fail => localization.G1Type2Fail,
G1TypeMatch1 => localization.G1TypeMatch1,
G1TypeMatch2 => localization.G1TypeMatch2,
G1TypeMatchPorygon => localization.G1TypeMatchPorygon,
G1TypePorygonFail => localization.G1TypePorygonFail,
G1TypePorygonFail1 => localization.G1TypePorygonFail1,
G1TypePorygonFail2 => localization.G1TypePorygonFail2,
G2InvalidTileTreeNotFound => localization.G2InvalidTileTreeNotFound,
G2TreeID => localization.G2TreeID,
G2OTGender => localization.G2OTGender,
G3EReader => localization.G3EReader,
G3OTGender => localization.G3OTGender,
G4InvalidTileR45Surf => localization.G4InvalidTileR45Surf,
G5IVAll30 => localization.G5IVAll30,
G5PIDShinyGrotto => localization.G5PIDShinyGrotto,
G5SparkleInvalid => localization.G5SparkleInvalid,
G5SparkleRequired => localization.G5SparkleRequired,
GanbaruStatLEQ_01 => localization.GanbaruStatTooHigh,
GenderInvalidNone => localization.GenderInvalidNone,
GeoBadOrder => localization.GeoBadOrder,
GeoHardwareInvalid => localization.GeoHardwareInvalid,
GeoHardwareRange => localization.GeoHardwareRange,
GeoHardwareValid => localization.GeoHardwareValid,
GeoMemoryMissing => localization.GeoMemoryMissing,
GeoNoCountryHT => localization.GeoNoCountryHT,
GeoNoRegion => localization.GeoNoRegion,
HintEvolvesToSpecies_0 => localization.HintEvolvesToSpecies_0,
HintEvolvesToRareForm_0 => localization.HintEvolvesToRareForm_0,
ItemEgg => localization.ItemEgg,
ItemUnreleased => localization.ItemUnreleased,
LevelEXPThreshold => localization.LevelEXPThreshold,
LevelEXPTooHigh => localization.LevelEXPTooHigh,
LevelMetBelow => localization.LevelMetBelow,
LevelMetGift => localization.LevelMetGift,
LevelMetGiftFail => localization.LevelMetGiftFail,
LevelMetSane => localization.LevelMetSane,
MemoryArgBadCatch_H => localization.MemoryArgBadCatch_H,
MemoryArgBadHatch_H => localization.MemoryArgBadHatch_H,
MemoryArgBadHT => localization.MemoryArgBadHT,
MemoryArgBadID_H => localization.MemoryArgBadID_H,
MemoryArgBadItem_H1 => localization.MemoryArgBadItem_H1,
MemoryArgBadLocation_H => localization.MemoryArgBadLocation_H,
MemoryArgBadMove_H1 => localization.MemoryArgBadMove_H1,
MemoryArgBadOTEgg_H => localization.MemoryArgBadOTEgg_H,
MemoryArgBadSpecies_H1 => localization.MemoryArgBadSpecies_H1,
MemoryArgSpecies_H => localization.MemoryArgSpecies_H,
MemoryCleared_H => localization.MemoryCleared_H,
MemoryValid_H => localization.MemoryValid_H,
MemoryFeelInvalid_H => localization.MemoryFeelInvalid_H,
MemoryHTFlagInvalid => localization.MemoryHTFlagInvalid,
MemoryHTGender_0 => localization.MemoryHTGender_0,
MemoryHTLanguage => localization.MemoryHTLanguage,
MemoryIndexArgHT => localization.MemoryIndexArgHT,
MemoryIndexFeel_H1 => localization.MemoryIndexFeel_H1,
MemoryIndexFeelHTLEQ9 => localization.MemoryIndexFeelHTLEQ9,
MemoryIndexID_H1 => localization.MemoryIndexID_H1,
MemoryIndexIntensity_H1 => localization.MemoryIndexIntensity_H1,
MemoryIndexIntensityHT1 => localization.MemoryIndexIntensityHT1,
MemoryIndexIntensityMin_H1 => localization.MemoryIndexIntensityMin_H1,
MemoryIndexLinkHT => localization.MemoryIndexLinkHT,
MemoryIndexVar_H1 => localization.MemoryIndexVar,
MemoryMissingHT => localization.MemoryMissingHT,
MemoryMissingOT => localization.MemoryMissingOT,
MemorySocialZero => localization.MemorySocialZero,
MemoryStatAffectionHT0 => localization.MemoryStatAffectionHT0,
MemoryStatAffectionOT0 => localization.MemoryStatAffectionOT0,
MemoryStatFriendshipHT0 => localization.MemoryStatFriendshipHT0,
MemoryStatFriendshipOTBaseEvent_0 => localization.MemoryStatFriendshipOTBaseEvent_0,
MemoryStatFullness_0 => localization.MemoryStatFullness_0,
MemoryStatFullnessLEQ_0 => localization.MemoryStatFullnessLEQ_0,
MemoryStatEnjoyment_0 => localization.MemoryStatEnjoyment_0,
MetDetailTimeOfDay => localization.MetDetailTimeOfDay,
MoveKeldeoMismatch => localization.MoveKeldeoMismatch,
MovesShouldMatchRelearnMoves => localization.MovesShouldMatchRelearnMoves,
MoveShopAlphaMoveShouldBeMastered_0 => localization.MoveShopAlphaMoveShouldBeMastered_0,
MoveShopAlphaMoveShouldBeOther => localization.MoveShopAlphaMoveShouldBeOther,
MoveShopAlphaMoveShouldBeZero => localization.MoveShopAlphaMoveShouldBeZero,
NickFlagEggNo => localization.NickFlagEggNo,
NickFlagEggYes => localization.NickFlagEggYes,
NickInvalidChar => localization.NickInvalidChar,
NickLengthLong => localization.NickLengthLong,
NickLengthShort => localization.NickLengthShort,
NickMatchLanguage => localization.NickMatchLanguage,
NickMatchLanguageEgg => localization.NickMatchLanguageEgg,
NickMatchLanguageEggFail => localization.NickMatchLanguageEggFail,
NickMatchLanguageFail => localization.NickMatchLanguageFail,
NickMatchLanguageFlag => localization.NickMatchLanguageFlag,
NickMatchNoOthers => localization.NickMatchNoOthers,
NickMatchNoOthersFail => localization.NickMatchNoOthersFail,
OTLanguage => localization.OTLanguage,
OTLanguageShouldBe_0 => localization.OTLanguageShouldBe_0,
OTLanguageShouldBe_0or1 => localization.OTLanguageShouldBe_0or1,
OTLanguageShouldBeLeq_0 => localization.OTLanguageShouldBeLeq_0,
OTLanguageCannotPlayOnVersion_0 => localization.OTLanguageCannotPlayOnVersion_0,
OTLanguageCannotTransferToConsoleRegion_0 => localization.OTLanguageCannotTransferToConsoleRegion_0,
OTLong => localization.OTLong,
OTShort => localization.OTShort,
OTSuspicious => localization.OTSuspicious,
OT_IDEqual => localization.OT_IDEqual,
OT_IDs0 => localization.OT_IDs0,
OT_SID0 => localization.OT_SID0,
OT_SID0Invalid => localization.OT_SID0Invalid,
OT_TID0 => localization.OT_TID0,
OT_IDInvalid => localization.OT_IDInvalid,
PIDEncryptWurmple => localization.PIDEncryptWurmple,
PIDEncryptZero => localization.PIDEncryptZero,
PIDEqualsEC => localization.PIDEqualsEC,
PIDGenderMatch => localization.PIDGenderMatch,
PIDGenderMismatch => localization.PIDGenderMismatch,
PIDNatureMatch => localization.PIDNatureMatch,
PIDNatureMismatch => localization.PIDNatureMismatch,
PIDTypeMismatch => localization.PIDTypeMismatch,
PIDZero => localization.PIDZero,
RibbonAllValid => localization.RibbonAllValid,
RibbonEgg => localization.RibbonEgg,
StatDynamaxInvalid => localization.StatDynamaxInvalid,
StatIncorrectHeight => localization.StatIncorrectHeight,
StatIncorrectHeightCopy => localization.StatIncorrectHeightCopy,
StatIncorrectHeightValue => localization.StatIncorrectHeightValue,
StatIncorrectWeight => localization.StatIncorrectWeight,
StatIncorrectWeightValue => localization.StatIncorrectWeightValue,
StatInvalidHeightWeight => localization.StatInvalidHeightWeight,
StatIncorrectCP_0 => localization.StatIncorrectCP,
StatGigantamaxInvalid => localization.StatGigantamaxInvalid,
StatGigantamaxValid => localization.StatGigantamaxValid,
StatNatureInvalid => localization.StatNatureInvalid,
StatBattleVersionInvalid => localization.StatBattleVersionInvalid,
StatNobleInvalid => localization.StatNobleInvalid,
StatAlphaInvalid => localization.StatAlphaInvalid,
StoredSourceEgg => localization.StoredSourceEgg,
SuperComplete => localization.SuperComplete,
SuperDistro => localization.SuperDistro,
SuperEgg => localization.SuperEgg,
SuperNoComplete => localization.SuperNoComplete,
SuperNoUnlocked => localization.SuperNoUnlocked,
SuperUnavailable => localization.SuperUnavailable,
SuperUnused => localization.SuperUnused,
TeraTypeIncorrect => localization.TeraTypeIncorrect,
TeraTypeMismatch => localization.TeraTypeMismatch,
TradeNotAvailable => localization.TradeNotAvailable,
TrainerIDNoSeed => localization.TrainerIDNoSeed,
TransferBad => localization.TransferBad,
TransferCurrentHandlerInvalid => localization.TransferCurrentHandlerInvalid,
TransferEgg => localization.TransferEgg,
TransferEggLocationTransporter => localization.TransferEggLocationTransporter,
TransferEggMetLevel => localization.TransferEggMetLevel,
TransferEggVersion => localization.TransferEggVersion,
TransferFlagIllegal => localization.TransferFlagIllegal,
TransferHandlerFlagRequired => localization.TransferHTFlagRequired,
TransferHandlerMismatchName => localization.TransferHTMismatchName,
TransferHandlerMismatchGender => localization.TransferHTMismatchGender,
TransferHandlerMismatchLanguage => localization.TransferHTMismatchLanguage,
TransferMet => localization.TransferMet,
TransferNotPossible => localization.TransferNotPossible,
TransferMetLocation => localization.TransferMetLocation,
TransferNature => localization.TransferNature,
TransferObedienceLevel => localization.TransferObedienceLevel,
TransferKoreanGen4 => localization.TransferKoreanGen4,
TransferEncryptGen6BitFlip => localization.TransferPIDECBitFlip,
TransferEncryptGen6Equals => localization.TransferPIDECEquals,
TransferEncryptGen6Xor => localization.TransferPIDECXor,
TransferTrackerMissing => localization.TransferTrackerMissing,
TransferTrackerShouldBeZero => localization.TransferTrackerShouldBeZero,
TrashBytesExpected => localization.TrashBytesExpected,
TrashBytesMismatchInitial => localization.TrashBytesMismatchInitial,
TrashBytesMissingTerminator => localization.TrashBytesMissingTerminator,
TrashBytesShouldBeEmpty => localization.TrashBytesShouldBeEmpty,
WordFilterInvalidCharacter_0 => localization.WordFilterInvalidCharacter_0,
WordFilterFlaggedPattern_01 => localization.WordFilterFlaggedPattern_01,
WordFilterTooManyNumbers_0 => localization.WordFilterTooManyNumbers_0,
BulkCloneDetectedDetails => localization.BulkCloneDetectedDetails,
BulkCloneDetectedTracker => localization.BulkCloneDetectedTracker,
BulkSharingEncryptionConstantGenerationSame => localization.BulkSharingEncryptionConstantGenerationSame,
BulkSharingEncryptionConstantGenerationDifferent => localization.BulkSharingEncryptionConstantGenerationDifferent,
BulkSharingEncryptionConstantEncounterType => localization.BulkSharingEncryptionConstantRNGType,
BulkSharingPIDGenerationDifferent => localization.BulkSharingPIDGenerationDifferent,
BulkSharingPIDGenerationSame => localization.BulkSharingPIDGenerationSame,
BulkSharingPIDEncounterType => localization.BulkSharingPIDRNGType,
BulkDuplicateMysteryGiftEggReceived => localization.BulkDuplicateMysteryGiftEggReceived,
BulkSharingTrainerIDs => localization.BulkSharingTrainerID,
BulkSharingTrainerVersion => localization.BulkSharingTrainerVersion,
>= MAX => throw new ArgumentOutOfRangeException(nameof(code), code, null),
};
}

View File

@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
public sealed class LegalityLocalizationSet
{
private static readonly Dictionary<string, LegalityLocalizationSet> Cache = new();
public required LegalityCheckLocalization Lines { get; init; }
public required GameStrings Strings { get; init; }
public required EncounterDisplayLocalization Encounter { get; init; }
public required MoveSourceLocalization Moves { get; init; }
public required GeneralLocalization General { get; init; }
public static LegalityLocalizationSet GetLocalization(LanguageID language) => GetLocalization(language.GetLanguageCode());
/// <summary>
/// Gets the localization for the requested language.
/// </summary>
/// <param name="language">Language code</param>
public static LegalityLocalizationSet GetLocalization(string language)
{
if (Cache.TryGetValue(language, out var result))
return result;
result = new LegalityLocalizationSet
{
Strings = GameInfo.GetStrings(language),
Lines = LegalityCheckLocalization.Get(language),
Encounter = EncounterDisplayLocalization.Get(language),
Moves = MoveSourceLocalization.Get(language),
General = GeneralLocalization.Get(language),
};
Cache[language] = result;
return result;
}
/// <summary>
/// Force loads all localizations.
/// </summary>
public static bool ForceLoadAll()
{
bool anyLoaded = false;
foreach (var lang in GameLanguage.AllSupportedLanguages)
{
if (Cache.ContainsKey(lang))
continue;
_ = GetLocalization(lang);
anyLoaded = true;
}
return anyLoaded;
}
/// <summary>
/// Gets all localizations.
/// </summary>
public static IReadOnlyDictionary<string, LegalityLocalizationSet> GetAll()
{
_ = ForceLoadAll();
return Cache;
}
}
public readonly ref struct LegalityLocalizationContext
{
public required LegalityAnalysis Analysis { get; init; }
public required LegalityLocalizationSet Settings { get; init; }
public GameStrings Strings => Settings.Strings;
/// <summary>
/// Creates a complete <see cref="LegalityLocalizationContext"/> with proper localization initialization.
/// </summary>
/// <param name="la">Legality analysis</param>
/// <param name="settings">Export settings</param>
/// <returns>Fully initialized localization context</returns>
public static LegalityLocalizationContext Create(LegalityAnalysis la, LegalityLocalizationSet settings) => new()
{
Analysis = la,
Settings = settings,
};
/// <summary>
/// Creates a complete <see cref="LegalityLocalizationContext"/> using the specified language.
/// </summary>
/// <param name="la">Legality analysis</param>
/// <param name="language">Language code</param>
/// <returns>Fully initialized localization context</returns>
public static LegalityLocalizationContext Create(LegalityAnalysis la, string language = GameLanguage.DefaultLanguage)
=> Create(la, LegalityLocalizationSet.GetLocalization(language));
public string GetRibbonMessage() => RibbonVerifier.GetMessage(Analysis, Strings.Ribbons, Settings.Lines);
public string GetStatName(int displayIndex) => GetSafe(Settings.General.StatNames, displayIndex);
public string GetMoveName(ushort move) => GetSafe(Strings.movelist, move);
public string GetSpeciesName(ushort species) => GetSafe(Strings.specieslist, species);
public string GetConsoleRegion3DS(int index) => GetSafe(Strings.console3ds, index);
public string GetRibbonName(int index) => GetSafe(Strings.ribbons, index);
public string GetLanguageName(int index) => GetSafe(Strings.languageNames, index);
private static string GetSafe(ReadOnlySpan<string> arr, int index)
{
if ((uint)index >= arr.Length)
return string.Empty;
return arr[index];
}
public string GetTrainer(int index) => index switch
{
0 => Settings.General.OriginalTrainer,
1 => Settings.General.HandlingTrainer,
_ => throw new ArgumentOutOfRangeException(nameof(index), $"Invalid Trainer argument: {index}"),
};
/// <summary>
/// Converts a <see cref="LegalityCheckResultCode"/> to its corresponding localized string,
/// applying formatting with the provided argument if needed.
/// </summary>
/// <param name="chk">Raw check value for formatting the string.</param>
/// <param name="verbose">Include Identifier</param>
/// <returns>The localized string from <see cref="LegalityCheckLocalization"/>, with formatting applied if needed</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when the enum value doesn't have a corresponding string</exception>
public string Humanize(in CheckResult chk, bool verbose = false)
{
var str = GetInternalString(chk);
var format = Settings.Lines.F0_1;
if (verbose)
str = string.Format(format, chk.Identifier.ToString(), str);
return string.Format(format, Description(chk.Judgement), str);
}
public string Description(Severity s) => s switch
{
Severity.Invalid => Settings.Lines.SInvalid,
Severity.Fishy => Settings.Lines.SFishy,
Severity.Valid => Settings.Lines.SValid,
_ => Settings.Lines.NotImplemented,
};
private string GetInternalString(CheckResult chk)
{
var code = chk.Result;
var template = code.GetTemplate(Settings.Lines);
if (code < FirstWithArgument)
return template;
if (code.IsArgument())
return string.Format(template, chk.Argument);
if (code.IsMove())
return string.Format(template, GetMoveName(chk.Argument));
if (code.IsLanguage())
return string.Format(template, GetLanguageName(chk.Argument), GetLanguageName(Analysis.Entity.Language));
if (code.IsMemory())
return GetMemory(chk, template, code);
// Complex codes may require additional context or arguments.
return GetComplex(chk, template, code);
}
private string GetMemory(CheckResult chk, string template, LegalityCheckResultCode code)
{
if (code is < FirstMemoryWithValue)
return string.Format(template, chk.Value);
if (code is MemoryArgBadItem_H1)
return string.Format(template, GetTrainer(chk.Argument), GetSpeciesName(chk.Argument2));
if (code is MemoryArgBadMove_H1)
return string.Format(template, GetTrainer(chk.Argument), GetMoveName(chk.Argument2));
if (code is MemoryArgBadSpecies_H1)
return string.Format(template, GetTrainer(chk.Argument), GetSpeciesName(chk.Argument2));
return string.Format(template, GetTrainer(chk.Argument), chk.Argument2);
}
private string GetComplex(CheckResult chk, string format, LegalityCheckResultCode code) => code switch
{
< FirstComplex => format, // why are you even here?
RibbonFInvalid_0 => string.Format(format, GetRibbonMessage()),
WordFilterFlaggedPattern_01 => string.Format(format, (WordFilterType)chk.Argument, WordFilter.GetPattern((WordFilterType)chk.Argument, chk.Argument2)),
WordFilterInvalidCharacter_0 => string.Format(format, chk.Argument.ToString("X4")),
AwakenedStatGEQ_01 => string.Format(format, chk.Argument, GetStatName(chk.Argument2)),
GanbaruStatLEQ_01 => string.Format(format, chk.Argument, GetStatName(chk.Argument2)),
OTLanguageCannotTransferToConsoleRegion_0 => string.Format(format, GetConsoleRegion3DS(chk.Argument)),
EncTradeShouldHaveEvolvedToSpecies_0 => string.Format(format, GetSpeciesName(chk.Argument)),
MoveEvoFCombination_0 => string.Format(format, GetSpeciesName(chk.Argument)),
HintEvolvesToSpecies_0 => string.Format(format, GetSpeciesName(chk.Argument)),
RibbonMarkingInvalid_0 => string.Format(format, GetRibbonName(chk.Argument)),
RibbonMarkingAffixed_0 => string.Format(format, GetRibbonName(chk.Argument)),
RibbonMissing_0 => string.Format(format, GetRibbonName(chk.Argument)),
StoredSlotSourceInvalid_0 => string.Format(format, (StorageSlotSource)chk.Argument),
HintEvolvesToRareForm_0 => string.Format(format, chk.Argument == 1),
OTLanguageShouldBe_0or1 => string.Format(format, GetLanguageName(chk.Argument), GetLanguageName(chk.Argument2), GetLanguageName(Analysis.Entity.Language)),
>= MAX => throw new ArgumentOutOfRangeException(nameof(code), code, null),
};
public string FormatMove(in MoveResult move, int index, byte currentFormat)
{
var result = Format(move, index, Settings.Moves.FormatMove);
var gen = move.Generation;
if (currentFormat != gen && gen != 0)
result += $" [Gen{gen}]";
return result;
}
public string FormatRelearn(in MoveResult move, int index) => Format(move, index, Settings.Moves.FormatRelearn);
private string Format(in MoveResult move, int index, string format) => string.Format(format, Description(move.Judgement), index, move.Summary(this));
}

View File

@ -0,0 +1,45 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
using System.Text.Json.Serialization;
namespace PKHeX.Core;
/// <summary>
/// Localization strings for move learning source information.
/// </summary>
public sealed class MoveSourceLocalization
{
private static readonly MoveSourceLocalizationContext Context = new(LocalizationStorage<MoveSourceLocalization>.Options);
public static readonly LocalizationStorage<MoveSourceLocalization> Cache = new("movesource", Context.MoveSourceLocalization);
public static MoveSourceLocalization Get(string language = GameLanguage.DefaultLanguage) => Cache.Get(language);
public static MoveSourceLocalization Get(LanguageID language) => Cache.Get(language.GetLanguageCode());
/// <summary>Format text for exporting a legality check result for a Move.</summary>
public required string FormatMove { get; init; } = "{0} Move {1}: {2}";
/// <summary>Format text for exporting a legality check result for a Relearn Move.</summary>
public required string FormatRelearn { get; init; } = "{0} Relearn Move {1}: {2}";
// Basic source types
public required string SourceDefault { get; init; } = "Default move.";
public required string SourceDuplicate { get; init; } = "Duplicate Move.";
public required string SourceEmpty { get; init; } = "Empty Move.";
public required string SourceInvalid { get; init; } = "Invalid Move.";
public required string SourceLevelUp { get; init; } = "Learned by Level-up.";
public required string SourceRelearn { get; init; } = "Relearnable Move.";
public required string SourceSpecial { get; init; } = "Special Non-Relearn Move.";
public required string SourceTMHM { get; init; } = "Learned by TM/HM.";
public required string SourceTutor { get; init; } = "Learned by Move Tutor.";
public required string SourceShared { get; init; } = "Shared Non-Relearn Move.";
// Egg-related sources
public required string RelearnEgg { get; init; } = "Base Egg move.";
public required string EggInherited { get; init; } = "Inherited Egg move.";
public required string EggTMHM { get; init; } = "Inherited TM/HM move.";
public required string EggInheritedTutor { get; init; } = "Inherited tutor move.";
public required string EggInvalid { get; init; } = "Not an expected Egg move.";
public required string EggLevelUp { get; init; } = "Inherited move learned by Level-up.";
}
[JsonSerializable(typeof(MoveSourceLocalization))]
public sealed partial class MoveSourceLocalizationContext : JsonSerializerContext;

View File

@ -1,6 +1,6 @@
using System;
using static PKHeX.Core.LearnMethod;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckLocalization;
namespace PKHeX.Core;
@ -94,62 +94,62 @@ public static class EggSourceUtil
/// <summary>
/// Unboxes the parse result and returns a user-friendly string for the move result.
/// </summary>
public static string GetSourceString(Array parse, byte generation, int index)
public static string GetSourceString(Array parse, byte generation, int index, MoveSourceLocalization loc)
{
if (index >= parse.Length)
return LMoveSourceEmpty;
return loc.SourceEmpty;
return generation switch
{
2 => ((EggSource2[])parse)[index].GetSourceString(),
3 or 4 => ((EggSource34[])parse)[index].GetSourceString(),
5 => ((EggSource5[])parse)[index].GetSourceString(),
>= 6 => ((EggSource6[])parse)[index].GetSourceString(),
_ => LMoveSourceEmpty,
2 => ((EggSource2[])parse)[index].GetSourceString(loc),
3 or 4 => ((EggSource34[])parse)[index].GetSourceString(loc),
5 => ((EggSource5[])parse)[index].GetSourceString(loc),
>= 6 => ((EggSource6[])parse)[index].GetSourceString(loc),
_ => loc.SourceEmpty,
};
}
private static string GetSourceString(this EggSource2 source) => source switch
private static string GetSourceString(this EggSource2 source, MoveSourceLocalization loc) => source switch
{
EggSource2.Base => LMoveRelearnEgg,
EggSource2.FatherEgg => LMoveEggInherited,
EggSource2.FatherTM => LMoveEggTMHM,
EggSource2.ParentLevelUp => LMoveEggLevelUp,
EggSource2.Tutor => LMoveEggInheritedTutor,
EggSource2.Base => loc.RelearnEgg,
EggSource2.FatherEgg => loc.EggInherited,
EggSource2.FatherTM => loc.EggTMHM,
EggSource2.ParentLevelUp => loc.EggLevelUp,
EggSource2.Tutor => loc.EggInheritedTutor,
EggSource2.Max => "Any",
_ => LMoveEggInvalid,
_ => loc.EggInvalid,
};
private static string GetSourceString(this EggSource34 source) => source switch
private static string GetSourceString(this EggSource34 source, MoveSourceLocalization loc) => source switch
{
EggSource34.Base => LMoveRelearnEgg,
EggSource34.FatherEgg => LMoveEggInherited,
EggSource34.FatherTM => LMoveEggTMHM,
EggSource34.ParentLevelUp => LMoveEggLevelUp,
EggSource34.Base => loc.RelearnEgg,
EggSource34.FatherEgg => loc.EggInherited,
EggSource34.FatherTM => loc.EggTMHM,
EggSource34.ParentLevelUp => loc.EggLevelUp,
EggSource34.Max => "Any",
EggSource34.VoltTackle => LMoveSourceSpecial,
_ => LMoveEggInvalid,
EggSource34.VoltTackle => loc.SourceSpecial,
_ => loc.EggInvalid,
};
private static string GetSourceString(this EggSource5 source) => source switch
private static string GetSourceString(this EggSource5 source, MoveSourceLocalization loc) => source switch
{
EggSource5.Base => LMoveRelearnEgg,
EggSource5.FatherEgg => LMoveEggInherited,
EggSource5.ParentLevelUp => LMoveEggLevelUp,
EggSource5.FatherTM => LMoveEggTMHM,
EggSource5.Base => loc.RelearnEgg,
EggSource5.FatherEgg => loc.EggInherited,
EggSource5.ParentLevelUp => loc.EggLevelUp,
EggSource5.FatherTM => loc.EggTMHM,
EggSource5.Max => "Any",
EggSource5.VoltTackle => LMoveSourceSpecial,
_ => LMoveEggInvalid,
EggSource5.VoltTackle => loc.SourceSpecial,
_ => loc.EggInvalid,
};
private static string GetSourceString(this EggSource6 source) => source switch
private static string GetSourceString(this EggSource6 source, MoveSourceLocalization loc) => source switch
{
EggSource6.Base => LMoveRelearnEgg,
EggSource6.ParentLevelUp => LMoveEggLevelUp,
EggSource6.ParentEgg => LMoveEggInherited,
EggSource6.Base => loc.RelearnEgg,
EggSource6.ParentLevelUp => loc.EggLevelUp,
EggSource6.ParentEgg => loc.EggInherited,
EggSource6.Max => "Any",
EggSource6.VoltTackle => LMoveSourceSpecial,
_ => LMoveEggInvalid,
EggSource6.VoltTackle => loc.SourceSpecial,
_ => loc.EggInvalid,
};
/// <summary>

View File

@ -36,6 +36,8 @@ internal static class EvolutionRestrictions
_ => NONE,
};
public static bool IsEvolvedSpeciesFormRare(uint encryptionConstant) => encryptionConstant % 100 is 0;
/// <summary>
/// Gets the species-form that it will evolve into.
/// </summary>

View File

@ -1,3 +1,4 @@
using System;
using static PKHeX.Core.LanguageID;
namespace PKHeX.Core;
@ -8,6 +9,14 @@ namespace PKHeX.Core;
/// <remarks>These values were specific to the 3DS games (Generations 6 and 7, excluding LGP/E)</remarks>
public static class Locale3DS
{
/// <summary>
/// List of defined Console Regions.
/// </summary>
/// <remarks>
/// 3 was reserved for AUS, but was later merged into Europe, so it is not a valid locale code.
/// </remarks>
public static ReadOnlySpan<byte> DefinedLocales => [0, 1, 2, /*3,*/ 4, 5, 6];
/// <summary>
/// Compares the <see cref="IRegionOrigin.ConsoleRegion"/> and <see cref="IRegionOrigin.Country"/> to determine if the country is available within that region.
/// </summary>

View File

@ -25,5 +25,5 @@ public abstract class MemoryContext
public abstract bool CanHaveIntensity(byte memory, byte intensity);
public abstract bool CanHaveFeeling(byte memory, byte feeling, ushort argument);
public abstract int GetMinimumIntensity(byte memory);
public abstract byte GetMinimumIntensity(byte memory);
}

View File

@ -154,5 +154,5 @@ public static byte GetMinimumIntensity6(int memory)
public override bool CanHaveIntensity(byte memory, byte intensity) => CanHaveIntensity6(memory, intensity);
public override bool CanHaveFeeling(byte memory, byte feeling, ushort argument) => CanHaveFeeling6(memory, feeling, argument);
public override int GetMinimumIntensity(byte memory) => GetMinimumIntensity6(memory);
public override byte GetMinimumIntensity(byte memory) => GetMinimumIntensity6(memory);
}

View File

@ -238,5 +238,5 @@ public static byte GetMinimumIntensity8(int memory)
public override bool CanHaveIntensity(byte memory, byte intensity) => CanHaveIntensity8(memory, intensity);
public override bool CanHaveFeeling(byte memory, byte feeling, ushort argument) => CanHaveFeeling8(memory, feeling, argument);
public override int GetMinimumIntensity(byte memory) => GetMinimumIntensity8(memory);
public override byte GetMinimumIntensity(byte memory) => GetMinimumIntensity8(memory);
}

View File

@ -1,5 +1,3 @@
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
/// <summary>
@ -10,12 +8,12 @@ namespace PKHeX.Core;
/// <param name="Variable">Argument for the memory</param>
/// <param name="Intensity">How strongly they remember the memory</param>
/// <param name="Feeling">How they feel about the memory</param>
public readonly record struct MemoryVariableSet(string Handler, byte MemoryID, ushort Variable, byte Intensity, byte Feeling)
public readonly record struct MemoryVariableSet(byte Handler, byte MemoryID, ushort Variable, byte Intensity, byte Feeling)
{
public static MemoryVariableSet Read(ITrainerMemories pk, int handler) => handler switch
{
0 => new(L_XOT, pk.OriginalTrainerMemory, pk.OriginalTrainerMemoryVariable, pk.OriginalTrainerMemoryIntensity, pk.OriginalTrainerMemoryFeeling), // OT
1 => new(L_XHT, pk.HandlingTrainerMemory, pk.HandlingTrainerMemoryVariable, pk.HandlingTrainerMemoryIntensity, pk.HandlingTrainerMemoryFeeling), // HT
_ => new(L_XOT, 0, 0, 0, 0),
0 => new(0, pk.OriginalTrainerMemory, pk.OriginalTrainerMemoryVariable, pk.OriginalTrainerMemoryIntensity, pk.OriginalTrainerMemoryFeeling), // OT
1 => new(1, pk.HandlingTrainerMemory, pk.HandlingTrainerMemoryVariable, pk.HandlingTrainerMemoryIntensity, pk.HandlingTrainerMemoryFeeling), // HT
_ => new(0, 0, 0, 0, 0),
};
}

View File

@ -1,5 +1,4 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace PKHeX.Core;
@ -33,7 +32,7 @@ internal static Regex[] LoadPatterns(ReadOnlySpan<char> patterns)
/// <param name="regexes">Console regex set to check against.</param>
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
internal static bool TryMatch(ReadOnlySpan<char> message, ReadOnlySpan<Regex> regexes, [NotNullWhen(true)] out string? regMatch)
internal static bool TryMatch(ReadOnlySpan<char> message, ReadOnlySpan<Regex> regexes, out int regMatch)
{
// Clean the string
Span<char> clean = stackalloc char[message.Length];
@ -41,76 +40,114 @@ internal static bool TryMatch(ReadOnlySpan<char> message, ReadOnlySpan<Regex> re
if (ctr != clean.Length)
clean = clean[..ctr];
foreach (var regex in regexes)
for (var i = 0; i < regexes.Length; i++)
{
var regex = regexes[i];
foreach (var _ in regex.EnumerateMatches(clean))
{
regMatch = regex.ToString();
regMatch = i;
return true;
}
}
regMatch = null;
regMatch = -1;
return false;
}
/// <inheritdoc cref="IsFiltered(ReadOnlySpan{char}, out string?, EntityContext, EntityContext)"/>
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch,
EntityContext current)
=> IsFiltered(message, out regMatch, current, current);
/// <inheritdoc cref="IsFiltered(ReadOnlySpan{char}, EntityContext, EntityContext, out WordFilterType, out int)"/>
public static bool IsFiltered(ReadOnlySpan<char> message, EntityContext current, out WordFilterType type, out int regMatch)
=> IsFiltered(message, current, current, out type, out regMatch);
/// <summary>
/// Checks to see if a phrase contains filtered content.
/// </summary>
/// <param name="message">Phrase to check for</param>
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <param name="current">Current context to check.</param>
/// <param name="original">Earliest context to check.</param>
/// <param name="type">Word filter set that matched the phrase.</param>
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch,
EntityContext current, EntityContext original)
public static bool IsFiltered(ReadOnlySpan<char> message, EntityContext current, EntityContext original, out WordFilterType type, out int regMatch)
{
regMatch = null;
regMatch = -1;
if (message.IsWhiteSpace() || message.Length <= 1)
{
type = WordFilterType.None;
return false;
}
// Only check against the single filter if requested
if (ParseSettings.Settings.WordFilter.DisableWordFilterPastGen)
return IsFilteredCurrentOnly(message, ref regMatch, current, original);
{
if (IsFilteredCurrentOnly(message, current, original, out regMatch))
{
type = WordFilterTypeExtensions.GetName(current);
return true;
}
type = WordFilterType.None;
return false;
}
return IsFilteredLookBack(message, out regMatch, current, original);
return IsFilteredLookBack(message, current, original, out type, out regMatch);
}
private static bool IsFilteredCurrentOnly(ReadOnlySpan<char> message, [NotNullWhen(true)] ref string? regMatch,
EntityContext current, EntityContext original) => current switch
private static bool IsFilteredCurrentOnly(ReadOnlySpan<char> message, EntityContext current, EntityContext original, out int regMatch)
{
EntityContext.Gen5 => WordFilter5.IsFiltered(message, out regMatch),
EntityContext.Gen6 => WordFilter3DS.IsFilteredGen6(message, out regMatch),
EntityContext.Gen7 when original is EntityContext.Gen6
=> WordFilter3DS.IsFilteredGen6(message, out regMatch),
EntityContext.Gen7 => WordFilter3DS.IsFilteredGen7(message, out regMatch),
_ => current.GetConsole() switch
regMatch = 0;
return current switch
{
GameConsole.NX => WordFilterNX.IsFiltered(message, out regMatch, original),
_ => false,
},
};
EntityContext.Gen5 => WordFilter5.IsFiltered(message, out regMatch),
private static bool IsFilteredLookBack(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch,
EntityContext current, EntityContext original)
EntityContext.Gen6 => WordFilter3DS.IsFilteredGen6(message, out regMatch),
EntityContext.Gen7 when original is EntityContext.Gen6
=> WordFilter3DS.IsFilteredGen6(message, out regMatch),
EntityContext.Gen7 => WordFilter3DS.IsFilteredGen7(message, out regMatch),
_ => current.GetConsole() switch
{
GameConsole.NX => WordFilterNX.IsFiltered(message, out regMatch, original),
_ => false,
},
};
}
private static bool IsFilteredLookBack(ReadOnlySpan<char> message, EntityContext current, EntityContext original, out WordFilterType type, out int regMatch)
{
// Switch 2 backwards transfer? Won't know for another couple years.
if (WordFilterNX.IsFiltered(message, out regMatch, original))
{
type = WordFilterType.NintendoSwitch;
return true;
}
var generation = original.Generation();
if (generation > 7 || original is EntityContext.Gen7b)
{
type = WordFilterType.None;
return false;
if (WordFilter3DS.IsFiltered(message, out regMatch, original))
return true;
}
return generation == 5 && WordFilter5.IsFiltered(message, out regMatch);
if (WordFilter3DS.IsFiltered(message, out regMatch, original))
{
type = WordFilterType.Nintendo3DS;
return true;
}
if (generation == 5 && WordFilter5.IsFiltered(message, out regMatch))
{
type = WordFilterType.Gen5;
return true;
}
// no other word filters (none in Gen3 or Gen4)
type = WordFilterType.None;
return false;
}
public static string GetPattern(WordFilterType chkArgument, int index) => chkArgument switch
{
WordFilterType.Gen5 => WordFilter5.GetPattern(index),
WordFilterType.Nintendo3DS => WordFilter3DS.GetPattern(index),
WordFilterType.NintendoSwitch => WordFilterNX.GetPattern(index),
_ => string.Empty,
};
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace PKHeX.Core;
@ -12,24 +11,25 @@ public static class WordFilter3DS
{
private static readonly Regex[] Regexes = WordFilter.LoadPatterns(Util.GetStringResource("badwords_3ds"));
public static string GetPattern(int index) => Regexes[index].ToString();
/// <summary>
/// Regex patterns to check against
/// </summary>
/// <remarks>No need to keep the original pattern strings around; the <see cref="Regex"/> object retrieves this via <see cref="Regex.ToString()"/></remarks>
private static readonly ConcurrentDictionary<string, string?>.AlternateLookup<ReadOnlySpan<char>> Lookup =
new ConcurrentDictionary<string, string?>().GetAlternateLookup<ReadOnlySpan<char>>();
private static readonly ConcurrentDictionary<string, int>.AlternateLookup<ReadOnlySpan<char>> PreviouslyChecked =
new ConcurrentDictionary<string, int>().GetAlternateLookup<ReadOnlySpan<char>>();
private const int MAX_COUNT = (1 << 17) - 1; // arbitrary cap for max dictionary size
private const int NoMatch = -1;
/// <inheritdoc cref="IsFiltered"/>
/// <remarks>Generation 6 is case-sensitive.</remarks>
public static bool IsFilteredGen6(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch)
=> IsFiltered(message, out regMatch, EntityContext.Gen6);
public static bool IsFilteredGen6(ReadOnlySpan<char> message, out int regMatch) => IsFiltered(message, out regMatch, EntityContext.Gen6);
/// <inheritdoc cref="IsFiltered"/>
/// <remarks>Generation 7 is case-insensitive.</remarks>
public static bool IsFilteredGen7(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch)
=> IsFiltered(message, out regMatch, EntityContext.Gen7);
public static bool IsFilteredGen7(ReadOnlySpan<char> message, out int regMatch) => IsFiltered(message, out regMatch, EntityContext.Gen7);
/// <summary>
/// Checks to see if a phrase contains filtered content.
@ -38,27 +38,27 @@ public static bool IsFilteredGen7(ReadOnlySpan<char> message, [NotNullWhen(true)
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <param name="original">Earliest context to check.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch, EntityContext original)
public static bool IsFiltered(ReadOnlySpan<char> message, out int regMatch, EntityContext original)
{
regMatch = null;
regMatch = NoMatch;
if (IsSpeciesName(message, original))
return false;
// Check dictionary
if (Lookup.TryGetValue(message, out regMatch))
return regMatch is not null;
if (PreviouslyChecked.TryGetValue(message, out regMatch))
return regMatch is not NoMatch;
// not in dictionary, check patterns
if (WordFilter.TryMatch(message, Regexes, out regMatch))
{
Lookup.TryAdd(message, regMatch);
PreviouslyChecked.TryAdd(message, regMatch);
return true;
}
// didn't match any pattern, cache result
if ((Lookup.Dictionary.Count & ~MAX_COUNT) != 0)
Lookup.Dictionary.Clear(); // reset
Lookup.TryAdd(message, regMatch = null);
if ((PreviouslyChecked.Dictionary.Count & ~MAX_COUNT) != 0)
PreviouslyChecked.Dictionary.Clear(); // reset
PreviouslyChecked.TryAdd(message, regMatch = NoMatch);
return false;
}

View File

@ -1,23 +1,32 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace PKHeX.Core;
public static class WordFilter5
{
private static readonly HashSet<string>.AlternateLookup<ReadOnlySpan<char>> Words =
new HashSet<string>(Util.GetStringList("badwords_gen5"))
private static readonly string[] BadWords = Util.GetStringList("badwords_gen5");
private static readonly Dictionary<string, int>.AlternateLookup<ReadOnlySpan<char>> Words = GetDictionary(BadWords)
.GetAlternateLookup<ReadOnlySpan<char>>();
public static string GetPattern(int index) => BadWords[index];
private static Dictionary<string, int> GetDictionary(ReadOnlySpan<string> input)
{
var result = new Dictionary<string, int>(input.Length);
for (int i = 0; i < input.Length; i++)
result[input[i]] = i;
return result;
}
/// <summary>
/// Checks to see if a phrase contains filtered content.
/// </summary>
/// <param name="message">Phrase to check</param>
/// <param name="match">Blocked word that filters the phrase.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? match)
public static bool IsFiltered(ReadOnlySpan<char> message, out int match)
{
Span<char> clean = stackalloc char[message.Length];
Normalize(message, clean);

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace PKHeX.Core;
@ -16,13 +15,16 @@ public static class WordFilterNX
/// <remarks>No need to keep the original pattern strings around; the <see cref="Regex"/> object retrieves this via <see cref="Regex.ToString()"/></remarks>
private static readonly Regex[] Regexes = WordFilter.LoadPatterns(Util.GetStringResource("badwords_switch"));
public static string GetPattern(int index) => Regexes[index].ToString();
/// <summary>
/// Due to some messages repeating (Trainer names), keep a list of repeated values for faster lookup.
/// </summary>
private static readonly ConcurrentDictionary<string, string?>.AlternateLookup<ReadOnlySpan<char>> Lookup =
new ConcurrentDictionary<string, string?>().GetAlternateLookup<ReadOnlySpan<char>>();
private static readonly ConcurrentDictionary<string, int>.AlternateLookup<ReadOnlySpan<char>> Lookup =
new ConcurrentDictionary<string, int>().GetAlternateLookup<ReadOnlySpan<char>>();
private const int MAX_COUNT = (1 << 17) - 1; // arbitrary cap for max dictionary size
private const int NoMatch = -1;
/// <summary>
/// Checks to see if a phrase contains filtered content.
@ -31,15 +33,15 @@ public static class WordFilterNX
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <param name="original">Earliest context to check.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch, EntityContext original)
public static bool IsFiltered(ReadOnlySpan<char> message, out int regMatch, EntityContext original)
{
regMatch = null;
regMatch = NoMatch;
if (IsSpeciesName(message, original))
return false;
// Check dictionary
if (Lookup.TryGetValue(message, out regMatch))
return regMatch is not null;
return regMatch is not NoMatch;
// not in dictionary, check patterns
if (WordFilter.TryMatch(message, Regexes, out regMatch))
@ -51,7 +53,7 @@ public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] ou
// didn't match any pattern, cache result
if ((Lookup.Dictionary.Count & ~MAX_COUNT) != 0)
Lookup.Dictionary.Clear(); // reset
Lookup.TryAdd(message, regMatch = null);
Lookup.TryAdd(message, regMatch = NoMatch);
return false;
}

View File

@ -0,0 +1,60 @@
using System;
namespace PKHeX.Core;
/// <summary>
/// Word filter contexts used by different <see cref="EntityContext"/>.
/// </summary>
public enum WordFilterType
{
/// <summary>
/// No strict filtering is applied.
/// </summary>
None,
/// <summary>
/// Generation 5 word filter, used for games like Black/White and Black 2/White 2.
/// </summary>
/// <remarks>
/// <see cref="WordFilter5"/>
/// </remarks>
Gen5,
/// <summary>
/// Generation 6 and 7 word filter, used for games like X/Y, Sun/Moon, Ultra Sun/Ultra Moon, and Sword/Shield.
/// </summary>
/// <remarks>
/// See <see cref="WordFilter3DS"/>
/// </remarks>
Nintendo3DS,
/// <summary>
/// Generation 8+ word filter.
/// </summary>
/// <remarks>
/// See <see cref="WordFilterNX"/>
/// </remarks>
NintendoSwitch,
}
public static class WordFilterTypeExtensions
{
public static WordFilterType GetName(EntityContext type) => type.GetConsole() switch
{
GameConsole.NX => WordFilterType.NintendoSwitch,
_ => type.Generation() switch
{
5 => WordFilterType.Gen5,
6 or 7 => WordFilterType.Nintendo3DS,
_ => WordFilterType.None,
},
};
public static Type GetType(WordFilterType type) => type switch
{
WordFilterType.Gen5 => typeof(WordFilter5),
WordFilterType.Nintendo3DS => typeof(WordFilter3DS),
WordFilterType.NintendoSwitch => typeof(WordFilterNX),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, $"Invalid {nameof(WordFilterType)} value."),
};
}

View File

@ -47,7 +47,6 @@ public static void Initialize(LegalitySettings settings)
public static IReadOnlyList<string> MoveStrings { get; private set; } = Util.GetMovesList(GameLanguage.DefaultLanguage);
public static IReadOnlyList<string> SpeciesStrings { get; private set; } = Util.GetSpeciesList(GameLanguage.DefaultLanguage);
public static string GetMoveName(ushort move) => move >= MoveStrings.Count ? LegalityCheckStrings.L_AError : MoveStrings[move];
public static void ChangeLocalizationStrings(IReadOnlyList<string> moves, IReadOnlyList<string> species)
{

View File

@ -168,4 +168,9 @@ public enum CheckIdentifier : byte
/// The <see cref="CheckResult"/> pertains to the <see cref="PKM"/> <see cref="StorageSlotType"/>.
/// </summary>
SlotType,
/// <summary>
/// The <see cref="CheckResult"/> pertains to the Current Handler (not OT) of the <see cref="PKM"/> data.
/// </summary>
Handler,
}

View File

@ -1,16 +1,51 @@
using System.Runtime.InteropServices;
namespace PKHeX.Core;
/// <summary>
/// Result of a Legality Check
/// </summary>
[System.Diagnostics.DebuggerDisplay($"{{{nameof(Identifier)}}}: {{{nameof(Comment)}}}")]
// ReSharper disable once NotAccessedPositionalProperty.Global
public readonly record struct CheckResult(Severity Judgement, CheckIdentifier Identifier, string Comment)
[System.Diagnostics.DebuggerDisplay($"{{{nameof(Identifier)}}}: {{{nameof(Result)}}}")]
[StructLayout(LayoutKind.Explicit, Size = 8)]
public readonly record struct CheckResult
{
/// <summary> Indicates whether the result is valid. </summary>
public bool Valid => Judgement != Severity.Invalid;
public string Rating => Judgement.Description();
internal CheckResult(CheckIdentifier i) : this(Severity.Valid, i, LegalityCheckStrings.L_AValid) { }
/// <summary> Indicates if the result isn't a generic "Valid" result, and might be worth displaying to the user. </summary>
public bool IsNotGeneric() => Result != LegalityCheckResultCode.Valid;
public string Format(string format) => string.Format(format, Rating, Comment);
/// <summary> Indicates the severity of the result. </summary>
[field: FieldOffset(0)] public required Severity Judgement { get; init; }
/// <summary> Identifier for the check group that produced this result. </summary>
[field: FieldOffset(1)] public required CheckIdentifier Identifier { get; init; }
/// <summary> Result code for the check, indicating the analysis performed/flagged to arrive at the <see cref="Judgement"/>. </summary>
[field: FieldOffset(2)] public required LegalityCheckResultCode Result { get; init; }
#region Hint Parameters used for Human-readable messages
/// <summary> Raw value used for hints, or storing a 32-bit number hint. </summary>
[field: FieldOffset(4)] public uint Value { get; init; }
/// <summary> First argument used for hints, or storing a 16-bit number hint. </summary>
[field: FieldOffset(4)] public ushort Argument { get; init; }
/// <summary> Second argument used for hints, or storing a 16-bit number hint. </summary>
[field: FieldOffset(6)] public ushort Argument2 { get; init; }
#endregion
/// <summary>
/// Simple method to create a valid result with the given identifier.
/// </summary>
public static CheckResult GetValid(CheckIdentifier ident) => Get(Severity.Valid, ident, LegalityCheckResultCode.Valid);
/// <summary>
/// Simple method to create a result with the given parameters.
/// </summary>
public static CheckResult Get(Severity judge, CheckIdentifier ident, LegalityCheckResultCode code, uint value = 0) => new()
{
Judgement = judge,
Identifier = ident,
Result = code,
Value = value,
};
}

View File

@ -0,0 +1,458 @@
namespace PKHeX.Core;
/// <summary>
/// Represents the specific type of legality result that was generated during a legality check.
/// </summary>
/// <remarks>
/// When a result is generated, instead of storing the string directly, an instance of this enum is stored instead.
/// The string is only fetched from <see cref="LegalityCheckLocalization"/> when needed for display.
/// </remarks>
public enum LegalityCheckResultCode : ushort
{
// General Strings
/// <summary>Default text for indicating validity.</summary>
Valid,
/// <summary>Default text for indicating an error has occurred.</summary>
Error,
// The order of the enum is important only for humanization; keep sorted by handling, with groups by category and functionality.
// Ability
AbilityCapsuleUsed,
AbilityPatchUsed,
AbilityPatchRevertUsed,
AbilityFlag,
AbilityHiddenFail,
AbilityHiddenUnavailable,
AbilityMismatch,
AbilityMismatch3,
AbilityMismatchFlag,
AbilityMismatchGift,
AbilityMismatchPID,
AbilityUnexpected,
// Awakened Values
AwakenedCap,
// Ball
BallAbility,
BallEggCherish,
BallEggMaster,
BallEnc,
BallEncMismatch,
BallHeavy,
BallSpecies,
BallSpeciesPass,
BallUnavailable,
// Contest
ContestZero,
ContestZeroSheen,
// Date & Timestamps
DateOutsideConsoleWindow,
DateTimeClockInvalid,
DateOutsideDistributionWindow,
// Egg
EggContest,
EggEXP,
EggHatchCycles,
EggLocation,
EggLocationInvalid,
EggLocationNone,
EggLocationPalPark,
EggLocationTrade,
EggLocationTradeFail,
EggMetLocationFail,
EggNature,
EggPokeathlon,
EggPP,
EggPPUp,
EggRelearnFlags,
EggShinyLeaf,
EggShinyPokeStar,
EggSpecies,
EggUnhatched,
// Encounter
EncCondition,
EncConditionBadRNGFrame,
EncConditionBadSpecies,
EncGift,
EncGiftEggEvent,
EncGiftIVMismatch,
EncGiftNicknamed,
EncGiftNotFound,
EncGiftPIDMismatch,
EncGiftShinyMismatch,
EncGiftVersionNotDistributed,
EncGiftRegionNotDistributed,
EncInvalid,
EncMasteryInitial,
EncTradeChangedNickname,
EncTradeChangedOT,
EncTradeIndexBad,
EncTradeMatch,
EncTradeUnchanged,
EncStaticPIDShiny,
EncTypeMatch,
EncTypeMismatch,
EncUnreleased,
EncUnreleasedEMewJP,
// E-Reader
EReaderAmerica,
EReaderInvalid,
EReaderJapan,
// Effort Values
Effort2Remaining,
EffortAbove252,
EffortAbove510,
EffortAllEqual,
EffortCap100,
EffortEgg,
EffortShouldBeZero,
EffortEXPIncreased,
// Evolution
EvoInvalid,
EvoTradeRequired,
// Fateful
FatefulGiftMissing,
FatefulInvalid,
FatefulMissing,
FatefulMystery,
FatefulMysteryMissing,
// Favorite Marking
FavoriteMarkingUnavailable,
// Form
FormArgumentNotAllowed,
FormArgumentValid,
FormArgumentInvalid,
FormBattle,
FormEternal,
FormEternalInvalid,
FormInvalidGame,
FormInvalidNature,
FormItemMatches,
FormItemInvalid,
FormParty,
FormPikachuCosplay,
FormPikachuCosplayInvalid,
FormPikachuEventInvalid,
FormInvalidExpect_0,
FormValid,
FormVivillon,
FormVivillonEventPre,
FormVivillonInvalid,
FormVivillonNonNative,
// Generation 1 & 2
G1CatchRateChain,
G1CatchRateEvo,
G1CatchRateItem,
G1CatchRateMatchPrevious,
G1CatchRateMatchTradeback,
G1CatchRateNone,
G1CharNick,
G1CharOT,
G1OTGender,
G1Stadium,
G1Type1Fail,
G1Type2Fail,
G1TypeMatch1,
G1TypeMatch2,
G1TypeMatchPorygon,
G1TypePorygonFail,
G1TypePorygonFail1,
G1TypePorygonFail2,
G2InvalidTileTreeNotFound,
G2TreeID,
G2OTGender,
// Generation 3+
G3EReader,
G3OTGender,
G4InvalidTileR45Surf,
G5IVAll30,
G5PIDShinyGrotto,
G5SparkleInvalid,
G5SparkleRequired,
// Gender
GenderInvalidNone,
// Geography
GeoBadOrder,
GeoHardwareInvalid,
GeoHardwareRange,
GeoHardwareValid,
GeoMemoryMissing,
GeoNoCountryHT,
GeoNoRegion,
// Hints
// Hyper Training
HyperPerfectAll,
HyperPerfectOne,
HyperPerfectUnavailable,
// Item
ItemEgg,
ItemUnreleased,
// IVs
IVNotCorrect,
// Level
LevelEXPThreshold,
LevelEXPTooHigh,
LevelMetBelow,
LevelMetGift,
LevelMetGiftFail,
LevelMetSane,
// Markings
MarkValueShouldBeZero,
MarkValueUnusedBitsPresent,
// Memory
MemoryArgBadHT,
MemoryHTFlagInvalid,
MemoryHTLanguage,
MemoryIndexArgHT,
MemoryIndexFeelHTLEQ9,
MemoryIndexIntensityHT1,
MemoryIndexLinkHT,
MemoryIndexVar_H1,
MemoryMissingHT,
MemoryMissingOT,
MemorySocialZero,
MemoryStatAffectionHT0,
MemoryStatAffectionOT0,
MemoryStatFriendshipHT0,
// Met Detail
MetDetailTimeOfDay,
// Moves - General
MoveKeldeoMismatch,
MovesShouldMatchRelearnMoves,
// Moves - Shop & Alpha
MoveShopAlphaMoveShouldBeOther,
MoveShopAlphaMoveShouldBeZero,
// Nickname
NickFlagEggNo,
NickFlagEggYes,
NickInvalidChar,
NickLengthLong,
NickLengthShort,
NickMatchLanguage,
NickMatchLanguageEgg,
NickMatchLanguageEggFail,
NickMatchLanguageFail,
NickMatchLanguageFlag,
NickMatchNoOthers,
NickMatchNoOthersFail,
// Original Trainer
OTLanguage,
OTLong,
OTShort,
OTSuspicious,
OT_IDEqual,
OT_IDs0,
OT_SID0,
OT_SID0Invalid,
OT_TID0,
OT_IDInvalid,
// PID & Encryption Constant
PIDEncryptWurmple,
PIDEncryptZero,
PIDEqualsEC,
PIDGenderMatch,
PIDGenderMismatch,
PIDNatureMatch,
PIDNatureMismatch,
PIDTypeMismatch,
PIDZero,
// Ribbons
RibbonAllValid,
RibbonEgg,
// Stats
StatDynamaxInvalid,
StatIncorrectHeight,
StatIncorrectHeightCopy,
StatIncorrectHeightValue,
StatIncorrectWeight,
StatIncorrectWeightValue,
StatInvalidHeightWeight,
StatGigantamaxInvalid,
StatGigantamaxValid,
StatNatureInvalid,
StatBattleVersionInvalid,
StatNobleInvalid,
StatAlphaInvalid,
// Storage
StoredSourceEgg,
// Super Training
SuperComplete,
SuperDistro,
SuperEgg,
SuperNoComplete,
SuperNoUnlocked,
SuperUnavailable,
SuperUnused,
// Tera Type
TeraTypeIncorrect,
TeraTypeMismatch,
// Trading
TradeNotAvailable,
// Trainer IDs
TrainerIDNoSeed,
// Transfer
TransferBad,
TransferCurrentHandlerInvalid,
TransferEgg,
TransferEggLocationTransporter,
TransferEggMetLevel,
TransferEggVersion,
TransferFlagIllegal,
TransferHandlerFlagRequired,
TransferHandlerMismatchName,
TransferHandlerMismatchGender,
TransferHandlerMismatchLanguage,
TransferMet,
TransferNotPossible,
TransferMetLocation,
TransferNature,
TransferObedienceLevel,
TransferKoreanGen4,
TransferEncryptGen6BitFlip,
TransferEncryptGen6Equals,
TransferEncryptGen6Xor,
TransferTrackerMissing,
TransferTrackerShouldBeZero,
TrashBytesExpected,
TrashBytesMismatchInitial,
TrashBytesMissingTerminator,
TrashBytesShouldBeEmpty,
// Bulk Cross-Comparison
BulkCloneDetectedDetails,
BulkCloneDetectedTracker,
BulkSharingEncryptionConstantGenerationSame,
BulkSharingEncryptionConstantGenerationDifferent,
BulkSharingEncryptionConstantEncounterType,
BulkSharingPIDGenerationDifferent,
BulkSharingPIDGenerationSame,
BulkSharingPIDEncounterType,
BulkDuplicateMysteryGiftEggReceived,
BulkSharingTrainerIDs,
BulkSharingTrainerVersion,
// Formattable Argument Present: 1 Number
FirstWithArgument,
ContestSheenGEQ_0 = FirstWithArgument,
MemoryStatFriendshipOTBaseEvent_0,
ContestSheenLEQ_0,
EggFMetLevel_0,
EffortUntrainedCap_0,
EvoTradeReqOutsider_0,
FormArgumentLEQ_0,
FormArgumentGEQ_0,
FormInvalidRange_0,
FormInvalidRangeLEQ_0,
HyperTrainLevelGEQ_0, // level
IVAllEqual_0,
IVFlawlessCountGEQ_0, // count
MarkValueOutOfRange_0, // unknown value
MemoryStatSocialLEQ_0,
MemoryStatFullness_0,
MemoryStatFullnessLEQ_0,
MemoryStatEnjoyment_0,
StatIncorrectCP_0, // value
WordFilterTooManyNumbers_0, // count
PokerusDaysLEQ_0, // days
PokerusStrainUnobtainable_0, // strain
MovePPExpectHealed_0, // move slot
MovePPTooHigh_0, // move slot
MovePPUpsTooHigh_0, // move slot
MemoryHTGender_0, // gender value
// Single Argument: Move ID
FirstWithMove,
MoveTechRecordFlagMissing_0 = FirstWithMove, // move ID
MoveShopAlphaMoveShouldBeMastered_0, // move
MoveShopMasterInvalid_0, // move ID
MoveShopMasterNotLearned_0, // move ID
MoveShopPurchaseInvalid_0, // move ID
// One Argument: Language
FirstWithLanguage,
OTLanguageShouldBe_0 = FirstWithLanguage, // language
OTLanguageShouldBeLeq_0, // language
EncGiftLanguageNotDistributed_0, // language
OTLanguageCannotPlayOnVersion_0, // language
// Multiple Arguments: Memories
FirstWithMemory,
MemoryValid_H = FirstWithMemory,
MemoryArgBadCatch_H,
MemoryArgBadHatch_H,
MemoryArgBadID_H,
MemoryArgBadLocation_H,
MemoryArgBadOTEgg_H,
MemoryArgSpecies_H,
MemoryCleared_H,
MemoryFeelInvalid_H,
FirstMemoryWithValue,
MemoryArgBadSpecies_H1 = FirstMemoryWithValue,
MemoryArgBadMove_H1,
MemoryArgBadItem_H1,
MemoryIndexID_H1,
MemoryIndexFeel_H1,
MemoryIndexIntensity_H1,
MemoryIndexIntensityMin_H1,
// One/Two Arguments: Special
FirstComplex,
RibbonFInvalid_0 = FirstComplex, // generated string
WordFilterFlaggedPattern_01, // filter, pattern
WordFilterInvalidCharacter_0, // filter, pattern
AwakenedStatGEQ_01,// value, statName
GanbaruStatLEQ_01, // value, statName
OTLanguageCannotTransferToConsoleRegion_0, // ConsoleRegion
EncTradeShouldHaveEvolvedToSpecies_0, // species
MoveEvoFCombination_0, // species
HintEvolvesToSpecies_0, // species
RibbonMarkingInvalid_0, // ribbon
RibbonMarkingAffixed_0, // ribbon
RibbonMissing_0, // ribbon
StoredSlotSourceInvalid_0, // StorageSlotType
HintEvolvesToRareForm_0, // bool
OTLanguageShouldBe_0or1, // language,language
MAX,
}

View File

@ -1,5 +1,3 @@
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
/// <summary> Severity indication of the associated <see cref="CheckResult"/> </summary>
@ -25,19 +23,3 @@ public enum Severity : sbyte
/// </summary>
Valid = 1,
}
public static partial class Extensions
{
/// <summary>
/// Converts a Check result Severity determination (Valid/Invalid/etc.) to the localized string.
/// </summary>
/// <param name="s"><see cref="Severity"/> value to convert to string.</param>
/// <returns>Localized <see cref="string"/>.</returns>
public static string Description(this Severity s) => s switch
{
Severity.Invalid => L_SInvalid,
Severity.Fishy => L_SFishy,
Severity.Valid => L_SValid,
_ => L_SNotImplemented,
};
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -15,8 +15,8 @@ public override void Verify(LegalityAnalysis data)
data.AddLine(result);
}
private CheckResult VALID => GetValid(LAbilityFlag);
private CheckResult INVALID => GetInvalid(LAbilityMismatch);
private CheckResult VALID => GetValid(AbilityFlag);
private CheckResult INVALID => GetInvalid(AbilityMismatch);
private enum AbilityState : byte
{
@ -33,7 +33,7 @@ private CheckResult VerifyAbility(LegalityAnalysis data)
int ability = pk.Ability;
int abilIndex = abilities.GetIndexOfAbility(ability);
if (abilIndex < 0)
return GetInvalid(LAbilityUnexpected);
return GetInvalid(AbilityUnexpected);
byte format = pk.Format;
if (format >= 6)
@ -59,7 +59,7 @@ private CheckResult VerifyAbility(LegalityAnalysis data)
var evos = data.Info.EvoChainsAllGens;
if (!AbilityChangeRules.IsAbilityCapsulePossible(evos))
return INVALID;
return GetValid(LAbilityCapsuleUsed);
return GetValid(AbilityCapsuleUsed);
}
}
}
@ -73,12 +73,12 @@ private CheckResult VerifyAbility(LegalityAnalysis data)
if (pk.AbilityNumber == 4)
{
if (AbilityChangeRules.IsAbilityPatchPossible(data.Info.EvoChainsAllGens))
return GetValid(LAbilityPatchUsed);
return GetValid(AbilityPatchUsed);
}
else if (enc.Ability == AbilityPermission.OnlyHidden)
{
if (AbilityChangeRules.IsAbilityPatchRevertPossible(data.Info.EvoChainsAllGens, pk.AbilityNumber))
return GetValid(LAbilityPatchRevertUsed);
return GetValid(AbilityPatchRevertUsed);
}
}
@ -100,7 +100,7 @@ private CheckResult VerifyAbility(LegalityAnalysis data, IPersonalAbility12 abil
if (eabil >= 0)
{
if ((data.Entity.AbilityNumber == 4) != (eabil == AbilityPermission.OnlyHidden))
return GetInvalid(LAbilityHiddenFail);
return GetInvalid(AbilityHiddenFail);
if (eabil > 0)
return VerifyFixedAbility(data, abilities, AbilityState.CanMismatch, eabil, abilIndex);
}
@ -129,7 +129,7 @@ private CheckResult VerifyAbility345(LegalityAnalysis data, IEncounterTemplate e
if (encounterAbility >= 0)
{
if ((pk.AbilityNumber == 4) != (encounterAbility == AbilityPermission.OnlyHidden))
return GetInvalid(LAbilityHiddenFail);
return GetInvalid(AbilityHiddenFail);
if (encounterAbility > 0)
return VerifyFixedAbility(data, abilities, state, encounterAbility, abilIndex);
}
@ -148,14 +148,14 @@ private CheckResult VerifyFixedAbility(LegalityAnalysis data, IPersonalAbility12
if (enc.Generation >= 6)
{
if (IsAbilityCapsuleModified(pk, encounterAbility, data.Info.EvoChainsAllGens, enc.Context))
return GetValid(LAbilityCapsuleUsed);
return GetValid(AbilityCapsuleUsed);
if (pk.AbilityNumber != 1 << encounterAbility.GetSingleValue())
return INVALID;
return VALID;
}
if ((pk.AbilityNumber == 4) != (encounterAbility == AbilityPermission.OnlyHidden))
return GetInvalid(LAbilityHiddenFail);
return GetInvalid(AbilityHiddenFail);
bool hasEvolved = enc.Species != pk.Species;
if (hasEvolved && state != AbilityState.CanMismatch)
@ -187,7 +187,7 @@ private CheckResult VerifyFixedAbility(LegalityAnalysis data, IPersonalAbility12
return CheckMatch(pk, abilities, enc.Generation, AbilityState.MustMatch, enc);
if (IsAbilityCapsuleModified(pk, encounterAbility, data.Info.EvoChainsAllGens, enc.Context))
return GetValid(LAbilityCapsuleUsed);
return GetValid(AbilityCapsuleUsed);
return INVALID;
}
@ -248,7 +248,7 @@ private AbilityState VerifyAbilityGen3Transfer(LegalityAnalysis data, IPersonalA
// If we reach here, it has not evolved in Gen4/5 games or has an invalid ability.
// The ability does not need to match the PIDAbility, but only Gen3 ability is allowed.
if (pk.Ability != pers.Ability1) // Not evolved in Gen4/5, but doesn't have Gen3 only ability
data.AddLine(GetInvalid(LAbilityMismatch3)); // probably bad to do this here
data.AddLine(GetInvalid(AbilityMismatch3)); // probably bad to do this here
return AbilityState.CanMismatch;
}
@ -260,14 +260,14 @@ private CheckResult VerifyAbilityMG(LegalityAnalysis data, MysteryGift g, IPerso
var pk = data.Entity;
if (g is PGT) // Ranger Manaphy
return (pk.Format >= 6 ? (pk.AbilityNumber == 1) : (pk.AbilityNumber < 4)) ? VALID : GetInvalid(LAbilityMismatchGift);
return (pk.Format >= 6 ? (pk.AbilityNumber == 1) : (pk.AbilityNumber < 4)) ? VALID : GetInvalid(AbilityMismatchGift);
var permit = g.Ability;
if (permit == AbilityPermission.Any12H)
return VALID;
int abilNumber = pk.AbilityNumber;
if (permit == AbilityPermission.Any12)
return abilNumber == 4 ? GetInvalid(LAbilityMismatchGift) : VALID;
return abilNumber == 4 ? GetInvalid(AbilityMismatchGift) : VALID;
// Only remaining matches are fixed index abilities
int cardAbilIndex = (int)permit;
@ -277,7 +277,7 @@ private CheckResult VerifyAbilityMG(LegalityAnalysis data, MysteryGift g, IPerso
// Can still match if the ability was changed via ability capsule...
// However, it can't change to/from Hidden Abilities.
if (abilNumber == 4 || permit == AbilityPermission.OnlyHidden)
return GetInvalid(LAbilityHiddenFail);
return GetInvalid(AbilityHiddenFail);
// Ability can be flipped 0/1 if Ability Capsule is available, is not Hidden Ability, and Abilities are different.
if (pk.Format >= 6)
@ -285,10 +285,10 @@ private CheckResult VerifyAbilityMG(LegalityAnalysis data, MysteryGift g, IPerso
// Maybe was evolved after using ability capsule.
var evos = data.Info.EvoChainsAllGens;
if (AbilityChangeRules.IsAbilityCapsulePossible(evos))
return GetValid(LAbilityCapsuleUsed);
return GetValid(AbilityCapsuleUsed);
}
return pk.Format < 6 ? GetInvalid(LAbilityMismatchPID) : INVALID;
return pk.Format < 6 ? GetInvalid(AbilityMismatchPID) : INVALID;
}
private CheckResult VerifyAbilityPCD(LegalityAnalysis data, IPersonalAbility12 abilities, PCD pcd)
@ -305,7 +305,7 @@ private CheckResult VerifyAbilityPCD(LegalityAnalysis data, IPersonalAbility12 a
return CheckMatch(pk, abilities, 4, AbilityState.MustMatch, pcd); // evolved, must match
}
if (pk.AbilityNumber < 4) // Ability Capsule can change between 1/2
return GetValid(LAbilityCapsuleUsed);
return GetValid(AbilityCapsuleUsed);
}
if (pcd.Species != pk.Species)
@ -322,7 +322,7 @@ private CheckResult VerifyAbility5(LegalityAnalysis data, IEncounterTemplate enc
// Eggs and Encounter Slots have not yet checked for Hidden Ability potential.
return enc switch
{
EncounterEgg5 egg when pk.AbilityNumber == 4 && !egg.Ability.CanBeHidden() => GetInvalid(LAbilityHiddenUnavailable),
EncounterEgg5 egg when pk.AbilityNumber == 4 && !egg.Ability.CanBeHidden() => GetInvalid(AbilityHiddenUnavailable),
_ => CheckMatch(data.Entity, abilities, 5, pk.Format == 5 ? AbilityState.MustMatch : AbilityState.CanMismatch, enc),
};
}
@ -335,7 +335,7 @@ private CheckResult VerifyAbility6(LegalityAnalysis data, IEncounterTemplate enc
return enc switch
{
EncounterEgg6 egg when !egg.Ability.CanBeHidden() => GetInvalid(LAbilityHiddenUnavailable),
EncounterEgg6 egg when !egg.Ability.CanBeHidden() => GetInvalid(AbilityHiddenUnavailable),
_ => VALID,
};
}
@ -348,7 +348,7 @@ private CheckResult VerifyAbility7(LegalityAnalysis data, IEncounterTemplate enc
return enc switch
{
EncounterEgg7 egg when !egg.Ability.CanBeHidden() => GetInvalid(LAbilityHiddenUnavailable),
EncounterEgg7 egg when !egg.Ability.CanBeHidden() => GetInvalid(AbilityHiddenUnavailable),
_ => VALID,
};
}
@ -361,7 +361,7 @@ private CheckResult VerifyAbility8BDSP(LegalityAnalysis data, IEncounterTemplate
return enc switch
{
EncounterEgg8b egg when !egg.Ability.CanBeHidden() => GetInvalid(LAbilityHiddenUnavailable),
EncounterEgg8b egg when !egg.Ability.CanBeHidden() => GetInvalid(AbilityHiddenUnavailable),
_ => VALID,
};
}
@ -377,7 +377,7 @@ private CheckResult VerifyAbility8BDSP(LegalityAnalysis data, IEncounterTemplate
private CheckResult CheckMatch(PKM pk, IPersonalAbility12 abilities, byte generation, AbilityState state, IEncounterTemplate enc)
{
if (generation is (3 or 4) && pk.AbilityNumber == 4)
return GetInvalid(LAbilityHiddenUnavailable);
return GetInvalid(AbilityHiddenUnavailable);
// other cases of hidden ability already flagged, all that is left is 1/2 mismatching
if (state != AbilityState.MustMatch)
@ -394,7 +394,7 @@ private CheckResult CheckMatch(PKM pk, IPersonalAbility12 abilities, byte genera
// Must not have the Ability bit flag set.
// Shadow encounters set a random ability index; don't bother checking if it's a re-battle for ability bit flipping.
if (abit && enc is not IShadow3)
return GetInvalid(LAbilityMismatchFlag, CheckIdentifier.PID);
return GetInvalid(CheckIdentifier.PID, AbilityMismatchFlag);
}
else
{
@ -402,7 +402,7 @@ private CheckResult CheckMatch(PKM pk, IPersonalAbility12 abilities, byte genera
// Version value check isn't factually correct, but there are no C/XD gifts with (Version!=15) that have two abilities.
// Pikachu, Celebi, Ho-Oh
if (pk.Version != GameVersion.CXD && abit != ((pk.EncryptionConstant & 1) == 1))
return GetInvalid(LAbilityMismatchPID, CheckIdentifier.PID);
return GetInvalid(CheckIdentifier.PID, AbilityMismatchPID);
}
}
else if (pk.Format >= 6)
@ -421,7 +421,7 @@ private CheckResult GetPIDAbilityMatch(PKM pk, IPersonalAbility abilities)
var index = pk.AbilityNumber >> 1;
var abil = abilities.GetAbilityAtIndex(index);
if (abil != pk.Ability)
return GetInvalid(LAbilityMismatchPID);
return GetInvalid(AbilityMismatchPID);
return VALID;
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -25,11 +25,11 @@ public override void Verify(LegalityAnalysis data)
// Can't obtain EVs in the game; only AVs.
int sum = pb7.EVTotal;
if (sum != 0)
data.AddLine(GetInvalid(LEffortShouldBeZero));
data.AddLine(GetInvalid(EffortShouldBeZero));
// Check that all AVs are within the allowed cap
if (!pb7.AwakeningAllValid())
data.AddLine(GetInvalid(LAwakenedCap));
data.AddLine(GetInvalid(AwakenedCap));
// Gather all AVs. When leveling up, AVs are "randomly" granted, so a mon must be at or above.
Span<byte> required = stackalloc byte[6];
@ -39,16 +39,16 @@ public override void Verify(LegalityAnalysis data)
// For each stat, ensure the current AV is at least the required minimum
if (current[0] < required[0])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[0], nameof(IAwakened.AV_HP))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[0], 0)); // HP
if (current[1] < required[1])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[1], nameof(IAwakened.AV_ATK))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[1], 1)); // Atk
if (current[2] < required[2])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[2], nameof(IAwakened.AV_DEF))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[2], 2)); // Def
if (current[3] < required[3])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[3], nameof(IAwakened.AV_SPA))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[3], 4)); // SpA
if (current[4] < required[4])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[4], nameof(IAwakened.AV_SPD))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[4], 5)); // SpD
if (current[5] < required[5])
data.AddLine(GetInvalid(string.Format(LAwakenedShouldBeValue, required[5], nameof(IAwakened.AV_SPE))));
data.AddLine(GetInvalid(Identifier, AwakenedStatGEQ_01, required[5], 3)); // Speed
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.Ball;
using static PKHeX.Core.BallVerificationResult;
@ -180,8 +180,8 @@ private static BallVerificationResult VerifyBallEggGen9(EncounterEgg9 enc, Ball
private CheckResult Localize(BallVerificationResult value)
{
bool valid = value.IsValid();
string msg = value.GetMessage();
return Get(msg, valid ? Severity.Valid : Severity.Invalid);
var msg = value.GetMessage();
return Get(valid ? Severity.Valid : Severity.Invalid, msg);
}
}
@ -210,17 +210,17 @@ public static class BallVerificationResultExtensions
_ => false,
};
public static string GetMessage(this BallVerificationResult value) => value switch
public static LegalityCheckResultCode GetMessage(this BallVerificationResult value) => value switch
{
ValidEncounter => LBallEnc,
ValidInheritedSpecies => LBallSpeciesPass,
BadEncounter => LBallEncMismatch,
BadCaptureHeavy => LBallHeavy,
BadInheritAbility => LBallAbility,
BadInheritSpecies => LBallSpecies,
BadInheritCherish => LBallEggCherish,
BadInheritMaster => LBallEggMaster,
BadOutOfRange => LBallUnavailable,
ValidEncounter => BallEnc,
ValidInheritedSpecies => BallSpeciesPass,
BadEncounter => BallEncMismatch,
BadCaptureHeavy => BallHeavy,
BadInheritAbility => BallAbility,
BadInheritSpecies => BallSpecies,
BadInheritCherish => BallEggCherish,
BadInheritMaster => BallEggMaster,
BadOutOfRange => BallUnavailable,
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null),
};
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -17,7 +17,7 @@ public override void Verify(LegalityAnalysis data)
// Colo starters are already hard-verified. No need to check them here.
if (pk.OriginalTrainerGender == 1)
data.AddLine(GetInvalid(LG3OTGender, CheckIdentifier.Trainer));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, G3OTGender));
// Trainer ID is checked in another verifier. Don't duplicate it here.
}
@ -34,7 +34,7 @@ private static void VerifyStarterXD(LegalityAnalysis data)
bool valid = MethodCXD.TryGetSeedStarterXD(pk, out var seed);
if (!valid)
data.AddLine(GetInvalid(LEncConditionBadRNGFrame, CheckIdentifier.PID));
data.AddLine(GetInvalid(CheckIdentifier.PID, EncConditionBadRNGFrame));
else
data.Info.PIDIV = new PIDIV(PIDType.CXD, seed);
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -24,7 +24,7 @@ private CheckResult VerifyConsoleRegion(IRegionOrigin pk)
{
var consoleRegion = pk.ConsoleRegion;
if (consoleRegion >= 7)
return GetInvalid(LGeoHardwareRange);
return GetInvalid(GeoHardwareRange);
return Verify3DSDataPresent(pk, consoleRegion);
}
@ -32,7 +32,7 @@ private CheckResult VerifyConsoleRegion(IRegionOrigin pk)
private CheckResult Verify3DSDataPresent(IRegionOrigin pk, byte consoleRegion)
{
if (!Locale3DS.IsConsoleRegionCountryValid(consoleRegion, pk.Country))
return GetInvalid(LGeoHardwareInvalid);
return GetValid(LGeoHardwareValid);
return GetInvalid(GeoHardwareInvalid);
return GetValid(GeoHardwareValid);
}
}

View File

@ -1,6 +1,6 @@
using static PKHeX.Core.ContestStatGranting;
using static PKHeX.Core.ContestStatInfo;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -29,14 +29,14 @@ public override void Verify(LegalityAnalysis data)
if (correlation == None)
{
// We're only here because we have contest stat values. We aren't permitted to have any, so flag it.
data.AddLine(GetInvalid(LContestZero));
data.AddLine(GetInvalid(ContestZero));
}
else if (correlation == NoSheen)
{
// We can get contest stat values, but we can't get any for Sheen.
// Any combination of non-sheen is ok, but nonzero sheen is illegal.
if (s.ContestSheen != 0)
data.AddLine(GetInvalid(LContestZeroSheen));
data.AddLine(GetInvalid(ContestZeroSheen));
}
else if (correlation == CorrelateSheen)
{
@ -50,12 +50,12 @@ public override void Verify(LegalityAnalysis data)
var minSheen = CalculateMinimumSheen(s, initial, pk, method);
if (s.ContestSheen < minSheen)
data.AddLine(GetInvalid(string.Format(LContestSheenTooLow_0, minSheen)));
data.AddLine(GetInvalid(ContestSheenGEQ_0, minSheen));
// Check for sheen values that are too high.
var maxSheen = CalculateMaximumSheen(s, pk.Nature, initial, gen3);
if (s.ContestSheen > maxSheen)
data.AddLine(GetInvalid(string.Format(LContestSheenTooHigh_0, maxSheen)));
data.AddLine(GetInvalid(ContestSheenLEQ_0, maxSheen));
}
else if (correlation == Mixed)
{
@ -65,7 +65,7 @@ public override void Verify(LegalityAnalysis data)
var initial = GetReferenceTemplate(data.Info.EncounterMatch);
var maxSheen = CalculateMaximumSheen(s, pk.Nature, initial, gen3);
if (s.ContestSheen > maxSheen)
data.AddLine(GetInvalid(string.Format(LContestSheenTooHigh_0, maxSheen)));
data.AddLine(GetInvalid(ContestSheenLEQ_0, maxSheen));
}
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -16,7 +16,7 @@ public override void Verify(LegalityAnalysis data)
if (pk.IsEgg)
{
if (pk.EVTotal is not 0)
data.AddLine(GetInvalid(LEffortEgg));
data.AddLine(GetInvalid(EffortEgg));
return;
}
@ -28,24 +28,24 @@ public override void Verify(LegalityAnalysis data)
int sum = pk.EVTotal;
if (sum > EffortValues.Max510) // format >= 3
data.AddLine(GetInvalid(LEffortAbove510));
data.AddLine(GetInvalid(EffortAbove510));
var enc = data.EncounterMatch;
Span<int> evs = stackalloc int[6];
pk.GetEVs(evs);
if (format >= 6 && IsAnyAboveHardLimit6(evs))
data.AddLine(GetInvalid(LEffortAbove252));
data.AddLine(GetInvalid(EffortAbove252));
else if (format < 5) // 3/4
VerifyGainedEVs34(data, enc, evs, pk);
// Only one of the following can be true: 0, 508, and x%6!=0
if (sum == 0 && !enc.IsWithinEncounterRange(pk))
data.AddLine(Get(LEffortEXPIncreased, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, EffortEXPIncreased));
else if (sum == EffortValues.MaxEffective)
data.AddLine(Get(LEffort2Remaining, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, Effort2Remaining));
else if (evs[0] != 0 && !evs.ContainsAnyExcept(evs[0]))
data.AddLine(Get(LEffortAllEqual, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, EffortAllEqual));
}
private void VerifyGainedEVs34(LegalityAnalysis data, IEncounterTemplate enc, ReadOnlySpan<int> evs, PKM pk)
@ -58,14 +58,14 @@ private void VerifyGainedEVs34(LegalityAnalysis data, IEncounterTemplate enc, Re
{
// Cannot EV train at level 100 -- Certain events are distributed at level 100.
// EVs can only be increased by vitamins to a max of 100.
data.AddLine(GetInvalid(LEffortCap100));
data.AddLine(GetInvalid(EffortCap100));
}
else // Check for gained EVs without gaining EXP -- don't check Gen5+ which have wings to boost above 100.
{
var growth = PersonalTable.HGSS[enc.Species].EXPGrowth;
var baseEXP = Experience.GetEXP(enc.LevelMin, growth);
if (baseEXP == pk.EXP)
data.AddLine(GetInvalid(string.Format(LEffortUntrainedCap, EffortValues.MaxVitamins34)));
data.AddLine(GetInvalid(EffortUntrainedCap_0, EffortValues.MaxVitamins34));
}
}

View File

@ -1,5 +1,6 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using System.Diagnostics.CodeAnalysis;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.Species;
namespace PKHeX.Core;
@ -26,79 +27,79 @@ private CheckResult VerifyFormArgument(LegalityAnalysis data, IFormArgument f)
var unusedMask = pk.Format == 6 ? 0xFFFF_FF00 : 0xFF00_0000;
if ((arg & unusedMask) != 0)
return GetInvalid(LFormArgumentHigh);
return GetInvalid(FormArgumentLEQ_0);
return (Species)pk.Species switch
{
// Transfer Edge Cases -- Bank wipes the form but keeps old FormArgument value.
Furfrou when pk is { Context: EntityContext.Gen7, Form: 0 } &&
((enc.Generation == 6 && f.FormArgument <= byte.MaxValue) || IsFormArgumentDayCounterValid(f, 5, true))
=> GetValid(LFormArgumentValid),
=> GetValid(FormArgumentValid),
Furfrou when pk.Form != 0 => !IsFormArgumentDayCounterValid(f, 5, true) ? GetInvalid(LFormArgumentInvalid) : GetValid(LFormArgumentValid),
Furfrou when pk.Form != 0 => !IsFormArgumentDayCounterValid(f, 5, true) ? GetInvalid(FormArgumentInvalid) : GetValid(FormArgumentValid),
Hoopa when pk.Form == 1 => data.Info.EvoChainsAllGens switch
{
{ HasVisitedGen9: true } when arg == 0 => GetValid(LFormArgumentValid), // Value not applied on form change, and reset when reverted.
{ HasVisitedGen6: true } when IsFormArgumentDayCounterValid(f, 3) => GetValid(LFormArgumentValid), // 0-3 via OR/AS
{ HasVisitedGen7: true } when IsFormArgumentDayCounterValid(f, 3) && f.FormArgumentRemain != 0 => GetValid(LFormArgumentValid), // 1-3 via Gen7
_ => GetInvalid(LFormArgumentInvalid),
{ HasVisitedGen9: true } when arg == 0 => GetValid(FormArgumentValid), // Value not applied on form change, and reset when reverted.
{ HasVisitedGen6: true } when IsFormArgumentDayCounterValid(f, 3) => GetValid(FormArgumentValid), // 0-3 via OR/AS
{ HasVisitedGen7: true } when IsFormArgumentDayCounterValid(f, 3) && f.FormArgumentRemain != 0 => GetValid(FormArgumentValid), // 1-3 via Gen7
_ => GetInvalid(FormArgumentInvalid),
},
Yamask when pk.Form == 1 => arg switch
{
not 0 when pk.IsEgg => GetInvalid(LFormArgumentNotAllowed),
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => GetValid(LFormArgumentValid),
not 0 when pk.IsEgg => GetInvalid(FormArgumentNotAllowed),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => GetValid(FormArgumentValid),
},
Basculin when pk.Form is 2 => arg switch
{
not 0 when pk.IsEgg => GetInvalid(LFormArgumentNotAllowed),
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => GetValid(LFormArgumentValid),
not 0 when pk.IsEgg => GetInvalid(FormArgumentNotAllowed),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => GetValid(FormArgumentValid),
},
Qwilfish when pk.Form is 1 => arg switch
{
not 0 when pk.IsEgg => GetInvalid(LFormArgumentNotAllowed),
not 0 when pk.CurrentLevel < 25 => GetInvalid(LFormArgumentHigh), // Can't get requisite move
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => GetValid(LFormArgumentValid),
not 0 when pk.IsEgg => GetInvalid(FormArgumentNotAllowed),
not 0 when pk.CurrentLevel < 25 => GetInvalid(FormArgumentLEQ_0, 0), // Can't get requisite move
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => GetValid(FormArgumentValid),
},
Overqwil => arg switch
{
> 9_999 => GetInvalid(LFormArgumentHigh),
0 when enc.Species == (ushort)Overqwil => GetValid(LFormArgumentValid),
< 20 when !data.Info.EvoChainsAllGens.HasVisitedGen9 || pk.CurrentLevel < (pk is IHomeTrack { HasTracker: true } ? 15 : 28) => GetInvalid(LFormArgumentLow),
>= 20 when !data.Info.EvoChainsAllGens.HasVisitedPLA || pk.CurrentLevel < 25 => GetInvalid(LFormArgumentLow),
_ when pk is IHomeTrack { HasTracker: false } and PA8 { CurrentLevel: < 25 } => GetInvalid(LEvoInvalid),
_ => GetValid(LFormArgumentValid),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
0 when enc.Species == (ushort)Overqwil => GetValid(FormArgumentValid),
< 20 when !data.Info.EvoChainsAllGens.HasVisitedGen9 || pk.CurrentLevel < (pk is IHomeTrack { HasTracker: true } ? 15 : 28) => GetInvalid(FormArgumentGEQ_0, 20),
>= 20 when !data.Info.EvoChainsAllGens.HasVisitedPLA || pk.CurrentLevel < 25 => GetInvalid(FormArgumentLEQ_0, 0),
_ when pk is IHomeTrack { HasTracker: false } and PA8 { CurrentLevel: < 25 } => GetInvalid(EvoInvalid),
_ => GetValid(FormArgumentValid),
},
Stantler => arg switch
{
not 0 when pk.IsEgg => GetInvalid(LFormArgumentNotAllowed),
not 0 when pk.CurrentLevel < 31 => GetInvalid(LFormArgumentHigh),
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => arg == 0 || HasVisitedPLA(data, Stantler) ? GetValid(LFormArgumentValid) : GetInvalid(LFormArgumentNotAllowed),
not 0 when pk.IsEgg => GetInvalid(FormArgumentNotAllowed),
not 0 when pk.CurrentLevel < 31 => GetInvalid(FormArgumentLEQ_0, 0),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => arg == 0 || HasVisitedPLA(data, Stantler) ? GetValid(FormArgumentValid) : GetInvalid(FormArgumentNotAllowed),
},
Primeape => arg switch
{
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => arg == 0 || HasVisitedSV(data, Primeape) ? GetValid(LFormArgumentValid) : GetInvalid(LFormArgumentNotAllowed),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => arg == 0 || HasVisitedSV(data, Primeape) ? GetValid(FormArgumentValid) : GetInvalid(FormArgumentNotAllowed),
},
Bisharp => arg switch
{
> 9_999 => GetInvalid(LFormArgumentHigh),
_ => arg == 0 || HasVisitedSV(data, Bisharp) ? GetValid(LFormArgumentValid) : GetInvalid(LFormArgumentNotAllowed),
> 9_999 => GetInvalid(FormArgumentLEQ_0, 9999),
_ => arg == 0 || HasVisitedSV(data, Bisharp) ? GetValid(FormArgumentValid) : GetInvalid(FormArgumentNotAllowed),
},
Gimmighoul => arg switch
{
// When leveled up, the game copies the save file's current coin count to the arg (clamped to <=999). If >=999, evolution is triggered.
// Without being leveled up at least once, it cannot have a form arg value.
>= 999 => GetInvalid(LFormArgumentHigh),
0 => GetValid(LFormArgumentValid),
_ => pk.CurrentLevel != pk.MetLevel ? GetValid(LFormArgumentValid) : GetInvalid(LFormArgumentNotAllowed),
>= 999 => GetInvalid(FormArgumentLEQ_0, 999),
0 => GetValid(FormArgumentValid),
_ => pk.CurrentLevel != pk.MetLevel ? GetValid(FormArgumentValid) : GetInvalid(FormArgumentNotAllowed),
},
Runerigus => VerifyFormArgumentRange(enc.Species, Runerigus, arg, 49, 9999),
Alcremie => VerifyFormArgumentRange(enc.Species, Alcremie, arg, 0, (uint)AlcremieDecoration.Ribbon),
Wyrdeer when enc.Species != (int)Wyrdeer && pk.CurrentLevel < 31 => GetInvalid(LEvoInvalid),
Alcremie => VerifyFormArgumentRange(enc.Species, Alcremie, arg, 0, (ushort)AlcremieDecoration.Ribbon),
Wyrdeer when enc.Species != (int)Wyrdeer && pk.CurrentLevel < 31 => GetInvalid(EvoInvalid),
Wyrdeer => VerifyFormArgumentRange(enc.Species, Wyrdeer, arg, 20, 9999),
Basculegion => VerifyFormArgumentRange(enc.Species, Basculegion, arg, 294, 9999),
Annihilape => VerifyFormArgumentRange(enc.Species, Annihilape, arg, 20, 9999),
@ -108,17 +109,17 @@ private CheckResult VerifyFormArgument(LegalityAnalysis data, IFormArgument f)
{
// Starter Legend has '1' when present in party, to differentiate.
// Cannot be traded to other games.
EncounterStatic9 { StarterBoxLegend: true } x when ParseSettings.ActiveTrainer is { } tr && (tr is not SAV9SV sv || sv.Version != x.Version) => GetInvalid(LTradeNotAvailable),
EncounterStatic9 { StarterBoxLegend: true } x when ParseSettings.ActiveTrainer is { } tr && (tr is not SAV9SV sv || sv.Version != x.Version) => GetInvalid(TradeNotAvailable),
EncounterStatic9 { StarterBoxLegend: true } => arg switch
{
< EncounterStatic9.RideLegendFormArg => GetInvalid(LFormArgumentLow),
EncounterStatic9.RideLegendFormArg => !data.IsStoredSlot(StorageSlotType.Ride) ? GetInvalid(LFormParty) : GetValid(LFormArgumentValid),
> EncounterStatic9.RideLegendFormArg => GetInvalid(LFormArgumentHigh),
< EncounterStatic9.RideLegendFormArg => GetInvalid(FormArgumentGEQ_0, EncounterStatic9.RideLegendFormArg),
EncounterStatic9.RideLegendFormArg => !data.IsStoredSlot(StorageSlotType.Ride) ? GetInvalid(FormParty) : GetValid(FormArgumentValid),
> EncounterStatic9.RideLegendFormArg => GetInvalid(FormArgumentLEQ_0, EncounterStatic9.RideLegendFormArg),
},
_ => arg switch
{
not 0 => GetInvalid(LFormArgumentNotAllowed),
_ => GetValid(LFormArgumentValid),
not 0 => GetInvalid(FormArgumentNotAllowed),
_ => GetValid(FormArgumentValid),
},
},
_ => VerifyFormArgumentNone(pk, f),
@ -137,22 +138,22 @@ private CheckResult VerifyFormArgument(LegalityAnalysis data, IFormArgument f)
/// <param name="value">Current Form Argument value</param>
/// <param name="min">Minimum value allowed</param>
/// <param name="max">Maximum value allowed</param>
private CheckResult VerifyFormArgumentRange(ushort encSpecies, Species check, uint value, uint min, uint max)
private CheckResult VerifyFormArgumentRange(ushort encSpecies, Species check, uint value, [ConstantExpected] ushort min, [ConstantExpected] ushort max)
{
// If was never the Form Argument accruing species (never evolved from it), then it must be zero.
if (encSpecies == (ushort)check)
{
if (value == 0)
return GetValid(LFormArgumentValid);
return GetInvalid(LFormArgumentNotAllowed);
return GetValid(FormArgumentValid);
return GetInvalid(FormArgumentNotAllowed);
}
// Evolved, must be within the range.
if (value < min)
return GetInvalid(LFormArgumentLow);
return GetInvalid(FormArgumentGEQ_0, min);
if (value > max)
return GetInvalid(LFormArgumentHigh);
return GetValid(LFormArgumentValid);
return GetInvalid(FormArgumentLEQ_0, max);
return GetValid(FormArgumentValid);
}
private CheckResult VerifyFormArgumentNone(PKM pk, IFormArgument f)
@ -162,26 +163,26 @@ private CheckResult VerifyFormArgumentNone(PKM pk, IFormArgument f)
if (f.FormArgument != 0)
{
if (pk is { Species: (int)Furfrou, Form: 0 } && (f.FormArgument & ~0xFF_00_00u) == 0)
return GetValid(LFormArgumentValid);
return GetInvalid(LFormArgumentNotAllowed);
return GetValid(FormArgumentValid);
return GetInvalid(FormArgumentNotAllowed);
}
return GetValid(LFormArgumentValid);
return GetValid(FormArgumentValid);
}
if (f.FormArgument != 0)
{
if (pk is { Species: (int)Furfrou, Form: 0 } && (f.FormArgument & ~0xFFu) == 0)
return GetValid(LFormArgumentValid);
return GetInvalid(LFormArgumentNotAllowed);
return GetValid(FormArgumentValid);
return GetInvalid(FormArgumentNotAllowed);
}
// Stored separately from main form argument value
if (pk6.FormArgumentRemain != 0)
return GetInvalid(LFormArgumentNotAllowed);
return GetInvalid(FormArgumentNotAllowed);
if (pk6.FormArgumentElapsed != 0)
return GetInvalid(LFormArgumentNotAllowed);
return GetInvalid(FormArgumentNotAllowed);
return GetValid(LFormArgumentValid);
return GetValid(FormArgumentValid);
}
private static bool IsFormArgumentDayCounterValid(IFormArgument f, uint maxSeed, bool canRefresh = false)

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.Species;
namespace PKHeX.Core;
@ -22,7 +22,7 @@ public override void Verify(LegalityAnalysis data)
FormArg.Verify(data);
}
private CheckResult VALID => GetValid(LFormValid);
private CheckResult VALID => GetValid(FormValid);
private CheckResult VerifyForm(LegalityAnalysis data)
{
@ -36,10 +36,9 @@ private CheckResult VerifyForm(LegalityAnalysis data)
var species = pk.Species;
var enc = data.EncounterMatch;
var Info = data.Info;
if (!pi.IsFormWithinRange(form) && !FormInfo.IsValidOutOfBoundsForm(species, form, enc.Generation))
return GetInvalid(string.Format(LFormInvalidRange, count - 1, form));
return GetInvalid(FormInvalidRange_0, (ushort)(count - 1));
switch ((Species)species)
{
@ -48,44 +47,48 @@ private CheckResult VerifyForm(LegalityAnalysis data)
{
if (form == 0)
break; // Regular Pikachu, OK.
return GetInvalid(LFormPikachuCosplay);
return GetInvalid(FormPikachuCosplay);
}
if (form != s6.Form)
return GetInvalid(LFormPikachuCosplayInvalid);
return GetInvalid(FormPikachuCosplayInvalid);
if (pk.Format != 6)
return GetInvalid(LTransferBad); // Can't transfer.
return GetInvalid(TransferBad); // Can't transfer.
break;
// LGP/E: Can't get the other game's Starter form.
case Pikachu when form is not 0 && ParseSettings.ActiveTrainer is SAV7b {Version:GameVersion.GE}:
case Eevee when form is not 0 && ParseSettings.ActiveTrainer is SAV7b {Version:GameVersion.GP}:
return GetInvalid(LFormBattle);
return GetInvalid(FormBattle);
case Pikachu when enc.Generation >= 7: // Cap
var expectForm = enc is EncounterInvalid or IEncounterEgg ? 0 : enc.Form;
if (form != expectForm)
{
bool gift = enc is MysteryGift g && g.Form != form;
var msg = gift ? LFormPikachuEventInvalid : LFormInvalidGame;
var msg = gift ? FormPikachuEventInvalid : FormInvalidGame;
return GetInvalid(msg);
}
break;
case Unown when enc.Generation == 2 && form >= 26:
return GetInvalid(string.Format(LFormInvalidRange, "Z", form == 26 ? "!" : "?"));
case Unown when enc.Generation == 3 && form != EntityPID.GetUnownForm3(pk.EncryptionConstant):
return GetInvalid(string.Format(LFormInvalidExpect_0, EntityPID.GetUnownForm3(pk.EncryptionConstant)));
case Dialga or Palkia or Giratina or Arceus when form > 0 && pk is PA8: // can change forms with key items
return GetInvalid(FormInvalidRangeLEQ_0, 25);
case Unown when enc.Generation == 3:
var expectUnown = EntityPID.GetUnownForm3(pk.EncryptionConstant);
if (expectUnown != form)
return GetInvalid(FormInvalidExpect_0, expectUnown);
break;
case Dialga or Palkia or Giratina or Arceus when form > 0 && pk is PA8: // can change forms with key items
break;
case Dialga when pk.Format >= 9 && ((form == 1) != (pk.HeldItem == 1777)): // Origin Forme Dialga with Adamant Crystal
case Palkia when pk.Format >= 9 && ((form == 1) != (pk.HeldItem == 1778)): // Origin Forme Palkia with Lustrous Globe
case Giratina when pk.Format >= 9 && ((form == 1) != (pk.HeldItem == 1779)): // Origin Forme Giratina with Griseous Core
case Giratina when pk.Format <= 8 && ((form == 1) != (pk.HeldItem == 0112)): // Origin Forme Giratina with Griseous Orb
return GetInvalid(LFormItemInvalid);
return GetInvalid(FormItemInvalid);
case Arceus:
var arceus = FormItem.GetFormArceus(pk.HeldItem, pk.Format);
return arceus != form ? GetInvalid(LFormItemInvalid) : GetValid(LFormItem);
return arceus != form ? GetInvalid(FormItemInvalid) : GetValid(FormItemMatches);
case Keldeo when enc.Generation != 5 || pk.Format >= 8:
// can mismatch in Gen5 via B/W tutor and transfer up
// can mismatch in Gen8+ as the form activates in battle when knowing the move; outside of battle can be either state.
@ -93,93 +96,93 @@ private CheckResult VerifyForm(LegalityAnalysis data)
bool hasSword = pk.HasMove((int) Move.SecretSword);
bool isSword = pk.Form == 1;
if (isSword != hasSword)
return GetInvalid(LMoveKeldeoMismatch);
return GetInvalid(MoveKeldeoMismatch);
break;
case Genesect:
var genesect = FormItem.GetFormGenesect(pk.HeldItem);
return genesect != form ? GetInvalid(LFormItemInvalid) : GetValid(LFormItem);
return genesect != form ? GetInvalid(FormItemInvalid) : GetValid(FormItemMatches);
case Greninja:
if (form > 1) // Ash Battle Bond active
return GetInvalid(LFormBattle);
return GetInvalid(FormBattle);
if (form != 0 && enc is not MysteryGift) // Form can not be bred for, MysteryGift already checked
return GetInvalid(string.Format(LFormInvalidRange, 0, form));
return GetInvalid(FormInvalidRange_0, 0);
break;
case Scatterbug or Spewpa or Vivillon when enc.Context is EntityContext.Gen9:
if (form > 18 && enc.Form != form) // Pokéball
return GetInvalid(LFormVivillonEventPre);
return GetInvalid(FormVivillonEventPre);
if (form != 18 && enc is IEncounterEgg) // Fancy
return GetInvalid(LFormVivillonNonNative);
return GetInvalid(FormVivillonNonNative);
break;
case Scatterbug or Spewpa:
if (form > Vivillon3DS.MaxWildFormID) // Fancy & Pokéball
return GetInvalid(LFormVivillonEventPre);
return GetInvalid(FormVivillonEventPre);
if (pk is not IRegionOrigin tr)
break;
if (!Vivillon3DS.IsPatternValid(form, tr.ConsoleRegion))
return GetInvalid(LFormVivillonInvalid);
return GetInvalid(FormVivillonInvalid);
if (!Vivillon3DS.IsPatternNative(form, tr.Country, tr.Region))
data.AddLine(Get(LFormVivillonNonNative, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, FormVivillonNonNative));
break;
case Vivillon:
if (form > Vivillon3DS.MaxWildFormID) // Fancy & Pokéball
{
if (enc is not MysteryGift)
return GetInvalid(LFormVivillonInvalid);
return GetValid(LFormVivillon);
return GetInvalid(FormVivillonInvalid);
return GetValid(FormVivillon);
}
if (pk is not IRegionOrigin trv)
break;
if (!Vivillon3DS.IsPatternValid(form, trv.ConsoleRegion))
return GetInvalid(LFormVivillonInvalid);
return GetInvalid(FormVivillonInvalid);
if (!Vivillon3DS.IsPatternNative(form, trv.Country, trv.Region))
data.AddLine(Get(LFormVivillonNonNative, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, FormVivillonNonNative));
break;
case Floette when form == 5: // Floette Eternal Flower -- Never Released
if (enc is not MysteryGift)
return GetInvalid(LFormEternalInvalid);
return GetValid(LFormEternal);
return GetInvalid(FormEternalInvalid);
return GetValid(FormEternal);
case Meowstic when form != pk.Gender:
return GetInvalid(LGenderInvalidNone);
return GetInvalid(GenderInvalidNone);
case Silvally:
var silvally = FormItem.GetFormSilvally(pk.HeldItem);
return silvally != form ? GetInvalid(LFormItemInvalid) : GetValid(LFormItem);
return silvally != form ? GetInvalid(FormItemInvalid) : GetValid(FormItemMatches);
// Form doesn't exist in SM; cannot originate from that game.
case Rockruff when enc.Generation == 7 && form == 1 && pk.SM:
case Lycanroc when enc.Generation == 7 && form == 2 && pk.SM:
return GetInvalid(LFormInvalidGame);
return GetInvalid(FormInvalidGame);
// Toxel encounters have already been checked for the nature-specific evolution criteria.
case Toxtricity when enc.Species == (int)Toxtricity:
// The game enforces the Nature for Toxtricity encounters too!
if (pk.Form != ToxtricityUtil.GetAmpLowKeyResult(pk.Nature))
return GetInvalid(LFormInvalidNature);
return GetInvalid(FormInvalidNature);
break;
// Ogerpon's form changes depending on its held mask
case Ogerpon when (form & 3) != FormItem.GetFormOgerpon(pk.HeldItem):
return GetInvalid(LFormItemInvalid);
return GetInvalid(FormItemInvalid);
// Impossible Egg forms
case Rotom when pk.IsEgg && form != 0:
case Furfrou when pk.IsEgg && form != 0:
return GetInvalid(LEggSpecies);
return GetInvalid(EggSpecies);
// Party Only Forms
case Shaymin:
case Furfrou:
case Hoopa:
if (form != 0 && !data.IsStoredSlot(StorageSlotType.Party) && pk.Format <= 6) // has form but stored in box
return GetInvalid(LFormParty);
return GetInvalid(FormParty);
break;
}
var format = pk.Format;
if (FormInfo.IsBattleOnlyForm(species, form, format))
return GetInvalid(LFormBattle);
return GetInvalid(FormBattle);
return VALID;
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -19,7 +19,7 @@ public override void Verify(LegalityAnalysis data)
// D/P/Pt & HG/SS Shedinja glitch -- only generation 4 spawns
bool ignore = pk is { Format: 4, Species: (int)Species.Shedinja } && pk.MetLevel != pk.CurrentLevel;
if (!ignore)
data.AddLine(GetInvalid(LGenderInvalidNone));
data.AddLine(GetInvalid(GenderInvalidNone));
return;
}
@ -28,7 +28,7 @@ public override void Verify(LegalityAnalysis data)
if (gen is 3 or 4 or 5)
{
// Gender-PID & Nature-PID relationship check
var result = IsValidGenderPID(data) ? GetValid(LPIDGenderMatch) : GetInvalid(LPIDGenderMismatch);
var result = IsValidGenderPID(data) ? GetValid(PIDGenderMatch) : GetInvalid(PIDGenderMismatch);
data.AddLine(result);
if (gen != 5)
@ -38,15 +38,15 @@ public override void Verify(LegalityAnalysis data)
// Check fixed gender cases
if ((pi.OnlyFemale && gender != 1) || (pi.OnlyMale && gender != 0))
data.AddLine(GetInvalid(LGenderInvalidNone));
data.AddLine(GetInvalid(GenderInvalidNone));
}
private static void VerifyNaturePID(LegalityAnalysis data)
{
var pk = data.Entity;
var result = GetExpectedNature(pk) == pk.Nature
? GetValid(LPIDNatureMatch, CheckIdentifier.Nature)
: GetInvalid(LPIDNatureMismatch, CheckIdentifier.Nature);
? GetValid(CheckIdentifier.Nature, PIDNatureMatch)
: GetInvalid(CheckIdentifier.Nature, PIDNatureMismatch);
data.AddLine(result);
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -18,7 +18,7 @@ public override void Verify(LegalityAnalysis data)
return;
var enc = data.EncounterMatch;
bool valid = IsGroundTileValid(enc, e);
var result = !valid ? GetInvalid(LEncTypeMismatch) : GetValid(LEncTypeMatch);
var result = !valid ? GetInvalid(EncTypeMismatch) : GetValid(EncTypeMatch);
data.AddLine(result);
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -68,22 +68,22 @@ private void VerifyTradeState(LegalityAnalysis data)
VerifyGeoLocationData(data, t, data.Entity);
if (pk.VC && pk is PK7 {Geo1_Country: 0}) // VC transfers set Geo1 Country
data.AddLine(GetInvalid(LGeoMemoryMissing));
data.AddLine(GetInvalid(GeoMemoryMissing));
if (!pk.IsUntraded)
{
// Can't have HT details even as a Link Trade egg, except in some games.
if (pk.IsEgg && !EggStateLegality.IsValidHTEgg(pk))
data.AddLine(GetInvalid(LMemoryArgBadHT));
data.AddLine(GetInvalid(MemoryArgBadHT));
return;
}
if (pk.CurrentHandler != 0) // Badly edited; PKHeX doesn't trip this.
data.AddLine(GetInvalid(LMemoryHTFlagInvalid));
data.AddLine(GetInvalid(MemoryHTFlagInvalid));
else if (pk.HandlingTrainerFriendship != 0)
data.AddLine(GetInvalid(LMemoryStatFriendshipHT0));
data.AddLine(GetInvalid(MemoryStatFriendshipHT0));
else if (pk is IAffection {HandlingTrainerAffection: not 0})
data.AddLine(GetInvalid(LMemoryStatAffectionHT0));
data.AddLine(GetInvalid(MemoryStatAffectionHT0));
// Don't check trade evolutions if Untraded. The Evolution Chain already checks for trade evolutions.
}
@ -106,7 +106,7 @@ private void VerifyHandlerState(LegalityAnalysis data, bool neverOT)
{
// generally disable this check if it's being edited inside a blank save file's environment.
if (tr is not SaveFile { State.Exportable: false })
data.AddLine(GetInvalid(LTransferCurrentHandlerInvalid));
data.AddLine(GetInvalid(TransferCurrentHandlerInvalid));
// if there's no HT data yet specified, don't bother checking further.
// blank save exports will be injected and fixed later, and not-blanks will have been flagged by the above.
if (pk.IsUntraded)
@ -118,9 +118,9 @@ private void VerifyHandlerState(LegalityAnalysis data, bool neverOT)
}
if (current != 1 && (enc.Context != pk.Context || neverOT))
data.AddLine(GetInvalid(LTransferHTFlagRequired));
data.AddLine(GetInvalid(TransferHandlerFlagRequired));
if (!pk.IsUntraded && IsUntradeableEncounter(enc)) // Starter, untradeable
data.AddLine(GetInvalid(LTransferCurrentHandlerInvalid));
data.AddLine(GetInvalid(TransferCurrentHandlerInvalid));
}
public static bool IsHandlerStateCorrect(IEncounterTemplate enc, PKM pk, byte current, byte expect)
@ -141,15 +141,15 @@ private void CheckHandlingTrainerEquals(LegalityAnalysis data, PKM pk, ITrainerI
ht = ht[..len];
if (!ht.SequenceEqual(tr.OT))
data.AddLine(GetInvalid(LTransferHTMismatchName));
data.AddLine(GetInvalid(TransferHandlerMismatchName));
if (pk.HandlingTrainerGender != tr.Gender)
data.AddLine(GetInvalid(LTransferHTMismatchGender));
data.AddLine(GetInvalid(TransferHandlerMismatchGender));
// If the format exposes a language, check if it matches.
// Can be mismatched as the game only checks OT/Gender equivalence -- if it matches, don't update everything else.
// Statistically unlikely that players will play in different languages, but it's technically possible.
if (pk is IHandlerLanguage h && h.HandlingTrainerLanguage != tr.Language)
data.AddLine(Get(LTransferHTMismatchLanguage, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, TransferHandlerMismatchLanguage));
}
private static bool IsUntradeableEncounter(IEncounterTemplate enc) => enc switch
@ -188,8 +188,9 @@ private void VerifyOTFriendship(LegalityAnalysis data, bool neverOT, byte genera
// If none match, then it is not a valid OT friendship.
var fs = pk.OriginalTrainerFriendship;
var enc = data.Info.EncounterMatch;
if (GetBaseFriendship(enc) != fs)
data.AddLine(GetInvalid(LMemoryStatFriendshipOTBaseEvent));
var expect = GetBaseFriendship(enc);
if (fs != expect)
data.AddLine(GetInvalid(MemoryStatFriendshipOTBaseEvent_0, expect));
}
}
@ -199,20 +200,22 @@ private void VerifyOTFriendshipVC12(LegalityAnalysis data, PKM pk)
// Since some evolutions have different base friendship values, check all possible evolutions for a match.
// If none match, then it is not a valid OT friendship.
// VC transfers use S/M personal info
var any = IsMatchFriendship(data.Info.EvoChainsAllGens.Gen7, pk.OriginalTrainerFriendship);
var any = IsMatchFriendship(data.Info.EvoChainsAllGens.Gen7, pk.OriginalTrainerFriendship, out var hint);
if (!any)
data.AddLine(GetInvalid(LMemoryStatFriendshipOTBaseEvent));
data.AddLine(GetInvalid(MemoryStatFriendshipOTBaseEvent_0, hint));
}
private static bool IsMatchFriendship(EvoCriteria[] evos, int fs)
private static bool IsMatchFriendship(ReadOnlySpan<EvoCriteria> evos, byte current, out byte expect)
{
expect = 0; // will be overridden on the first loop
var pt = PersonalTable.USUM;
foreach (var z in evos)
{
if (!pt.IsPresentInGame(z.Species, z.Form))
continue;
var entry = pt.GetFormEntry(z.Species, z.Form);
if (entry.BaseFriendship == fs)
expect = entry.BaseFriendship;
if (expect == current)
return true;
}
return false;
@ -228,7 +231,7 @@ private void VerifyOTAffection(LegalityAnalysis data, bool neverOT, int origin,
// Can gain affection in Gen6 via the Contest glitch applying affection to OT rather than HT.
// VC encounters cannot obtain OT affection since they can't visit Gen6.
if ((origin <= 2 && a.OriginalTrainerAffection != 0) || IsInvalidContestAffection(a))
data.AddLine(GetInvalid(LMemoryStatAffectionOT0));
data.AddLine(GetInvalid(MemoryStatAffectionOT0));
}
else if (neverOT)
{
@ -237,17 +240,17 @@ private void VerifyOTAffection(LegalityAnalysis data, bool neverOT, int origin,
if (pk is { IsUntraded: true, XY: true })
{
if (a.OriginalTrainerAffection != 0)
data.AddLine(GetInvalid(LMemoryStatAffectionOT0));
data.AddLine(GetInvalid(MemoryStatAffectionOT0));
}
else if (IsInvalidContestAffection(a))
{
data.AddLine(GetInvalid(LMemoryStatAffectionOT0));
data.AddLine(GetInvalid(MemoryStatAffectionOT0));
}
}
else
{
if (a.OriginalTrainerAffection != 0)
data.AddLine(GetInvalid(LMemoryStatAffectionOT0));
data.AddLine(GetInvalid(MemoryStatAffectionOT0));
}
}
}
@ -260,18 +263,18 @@ private void VerifyHTMisc(LegalityAnalysis data)
var pk = data.Entity;
var htGender = pk.HandlingTrainerGender;
if (htGender > 1 || (pk.IsUntraded && htGender != 0))
data.AddLine(GetInvalid(string.Format(LMemoryHTGender, htGender)));
data.AddLine(GetInvalid(MemoryHTGender_0, htGender));
}
private void VerifyGeoLocationData(LegalityAnalysis data, IGeoTrack t, PKM pk)
{
var valid = t.GetValidity();
if (valid == GeoValid.CountryAfterPreviousEmpty)
data.AddLine(GetInvalid(LGeoBadOrder));
data.AddLine(GetInvalid(GeoBadOrder));
else if (valid == GeoValid.RegionWithoutCountry)
data.AddLine(GetInvalid(LGeoNoRegion));
data.AddLine(GetInvalid(GeoNoRegion));
if (t.Geo1_Country != 0 && pk.IsUntraded) // traded
data.AddLine(GetInvalid(LGeoNoCountryHT));
data.AddLine(GetInvalid(GeoNoCountryHT));
}
// OR/AS contests mistakenly apply 20 affection to the OT instead of the current handler's value
@ -314,13 +317,13 @@ public static bool GetCanOTHandle(IEncounterTemplate enc, PKM pk, byte generatio
_ => false,
};
private static int GetBaseFriendship(IEncounterTemplate enc) => enc switch
private static byte GetBaseFriendship(IEncounterTemplate enc) => enc switch
{
IFixedOTFriendship f => f.OriginalTrainerFriendship,
_ => GetBaseFriendship(enc.Context, enc.Species, enc.Form),
};
private static int GetBaseFriendship(EntityContext context, ushort species, byte form) => context switch
private static byte GetBaseFriendship(EntityContext context, ushort species, byte form) => context switch
{
EntityContext.Gen6 => PersonalTable.AO[species].BaseFriendship,
EntityContext.Gen7 => PersonalTable.USUM[species].BaseFriendship,

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -20,21 +20,21 @@ public override void Verify(LegalityAnalysis data)
if (!t.IsHyperTrainingAvailable())
{
data.AddLine(GetInvalid(LHyperPerfectUnavailable));
data.AddLine(GetInvalid(HyperPerfectUnavailable));
return;
}
var minLevel = t.GetHyperTrainMinLevel(data.Info.EvoChainsAllGens, pk.Context);
if (pk.CurrentLevel < minLevel)
{
data.AddLine(GetInvalid(string.Format(LHyperTooLow_0, minLevel)));
data.AddLine(GetInvalid(HyperTrainLevelGEQ_0, (ushort)minLevel));
return;
}
int max = pk.MaxIV;
if (pk.IVTotal == max * 6)
{
data.AddLine(GetInvalid(LHyperPerfectAll));
data.AddLine(GetInvalid(HyperPerfectAll));
return;
}
@ -53,7 +53,7 @@ public override void Verify(LegalityAnalysis data)
}
if (IsFlawlessHyperTrained(pk, t, max))
data.AddLine(GetInvalid(LHyperPerfectOne));
data.AddLine(GetInvalid(HyperPerfectOne));
}
public static bool IsFlawlessHyperTrained(PKM pk, IHyperTrain t, int max)

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -30,7 +30,7 @@ public override void Verify(LegalityAnalysis data)
var pk = data.Entity;
var hp = pk.IV_HP;
if (hp < 30 && AllIVsEqual(pk, hp))
data.AddLine(Get(string.Format(LIVAllEqual_0, hp), Severity.Fishy));
data.AddLine(Get(Severity.Fishy, IVAllEqual_0, (ushort)hp));
}
private static bool AllIVsEqual(PKM pk, int hp) => pk.IV_ATK == hp
@ -51,7 +51,7 @@ private void VerifyIVsMystery(LegalityAnalysis data, MysteryGift g)
{
bool valid = Legal.GetIsFixedIVSequenceValidSkipRand(IVs, data.Entity);
if (!valid)
data.AddLine(GetInvalid(LEncGiftIVMismatch));
data.AddLine(GetInvalid(EncGiftIVMismatch));
}
else
{
@ -80,12 +80,12 @@ private void VerifyIVsFlawless(LegalityAnalysis data, IFlawlessIVCount s)
private void VerifyIVsFlawless(LegalityAnalysis data, int count)
{
if (data.Entity.FlawlessIVCount < count)
data.AddLine(GetInvalid(string.Format(LIVF_COUNT0_31, count)));
data.AddLine(GetInvalid(IVFlawlessCountGEQ_0, (ushort)count));
}
private void VerifyIVsGoTransfer(LegalityAnalysis data, IPogoSlot g)
{
if (!g.GetIVsValid(data.Entity))
data.AddLine(GetInvalid(LIVNotCorrect));
data.AddLine(GetInvalid(IVNotCorrect));
}
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -14,10 +14,10 @@ public override void Verify(LegalityAnalysis data)
var pk = data.Entity;
var item = pk.HeldItem;
if (pk.IsEgg && item != 0)
data.AddLine(GetInvalid(LItemEgg));
data.AddLine(GetInvalid(ItemEgg));
if (!ItemRestrictions.IsHeldItemAllowed(item, context: pk.Context))
data.AddLine(GetInvalid(LItemUnreleased));
data.AddLine(GetInvalid(ItemUnreleased));
else if (item == 175 && pk is G3PKM g3) // Enigma Berry
VerifyEnigmaGen3(data, g3);
}
@ -27,7 +27,7 @@ private void VerifyEnigmaGen3(LegalityAnalysis data, G3PKM g3)
// A Pokémon holding this Berry cannot be traded to Pokémon Colosseum or Pokémon XD: Gale of Darkness,
// nor can it be stored in Pokémon Box Ruby & Sapphire.
if (g3 is CK3 or XK3 || ParseSettings.ActiveTrainer is SAV3RSBox)
data.AddLine(GetInvalid(LItemUnreleased));
data.AddLine(GetInvalid(ItemUnreleased));
else
VerifyEReaderBerry(data);
}
@ -42,10 +42,10 @@ private void VerifyEReaderBerry(LegalityAnalysis data)
private CheckResult GetEReaderCheckResult(EReaderBerryMatch status) => status switch
{
EReaderBerryMatch.NoMatch => GetInvalid(LEReaderInvalid),
EReaderBerryMatch.NoData => GetInvalid(LItemUnreleased),
EReaderBerryMatch.InvalidUSA => GetInvalid(LEReaderAmerica),
EReaderBerryMatch.InvalidJPN => GetInvalid(LEReaderJapan),
EReaderBerryMatch.NoMatch => GetInvalid(EReaderInvalid),
EReaderBerryMatch.NoData => GetInvalid(ItemUnreleased),
EReaderBerryMatch.InvalidUSA => GetInvalid(EReaderAmerica),
EReaderBerryMatch.InvalidJPN => GetInvalid(EReaderJapan),
_ => default,
};
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.GameVersion;
using static PKHeX.Core.LanguageID;
@ -20,7 +20,7 @@ public override void Verify(LegalityAnalysis data)
var enc = data.EncounterMatch;
if (!IsValidLanguageID(currentLanguage, maxLanguageID, pk, enc))
{
data.AddLine(GetInvalid(string.Format(LOTLanguage, $"<={maxLanguageID}", currentLanguage)));
data.AddLine(GetInvalid(Identifier, OTLanguageShouldBeLeq_0, (byte)maxLanguageID, (byte)currentLanguage));
return;
}
@ -30,9 +30,7 @@ public override void Verify(LegalityAnalysis data)
)
{
bool kor = currentLanguage == Korean;
var msgpkm = kor ? L_XKorean : L_XKoreanNon;
var msgsav = kor ? L_XKoreanNon : L_XKorean;
data.AddLine(GetInvalid(string.Format(LTransferOriginFInvalid0_1, msgpkm, msgsav)));
data.AddLine(GetInvalid(TransferKoreanGen4));
return;
}
@ -40,11 +38,11 @@ public override void Verify(LegalityAnalysis data)
{
// Korean Crystal does not exist, neither do Korean VC1
if (pk is { Korean: true, Version: not (GD or SI) })
data.AddLine(GetInvalid(string.Format(LOTLanguage, $"!={currentLanguage}", currentLanguage)));
data.AddLine(GetInvalid(OTLanguageCannotPlayOnVersion_0, (byte)pk.Version));
// Japanese VC is language locked; cannot obtain Japanese-Blue version as other languages.
if (pk is { Japanese: false, Version: BU })
data.AddLine(GetInvalid(string.Format(LOTLanguage, nameof(Japanese), currentLanguage)));
data.AddLine(GetInvalid(OTLanguageCannotPlayOnVersion_0, (byte)pk.Version));
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -16,9 +16,9 @@ public override void Verify(LegalityAnalysis data)
return;
if (pa.IsNoble)
data.AddLine(GetInvalid(LStatNobleInvalid));
data.AddLine(GetInvalid(StatNobleInvalid));
if (pa.IsAlpha != data.EncounterMatch is IAlphaReadOnly { IsAlpha: true })
data.AddLine(GetInvalid(LStatAlphaInvalid));
data.AddLine(GetInvalid(StatAlphaInvalid));
CheckScalars(data, pa);
CheckGanbaru(data, pa);
@ -36,7 +36,7 @@ private static void CheckGanbaru(LegalityAnalysis data, PA8 pa)
if (gv <= max)
continue;
data.AddLine(GetInvalid(LGanbaruStatTooHigh, CheckIdentifier.GVs));
data.AddLine(GetInvalid(CheckIdentifier.GVs, GanbaruStatLEQ_01, max, (ushort)i));
return;
}
}
@ -47,14 +47,14 @@ private void CheckScalars(LegalityAnalysis data, PA8 pa)
if (pa.IsAlpha && data.EncounterMatch is EncounterSlot8a)
{
if (pa.HeightScalar != 255)
data.AddLine(GetInvalid(LStatIncorrectHeightValue));
data.AddLine(GetInvalid(StatIncorrectHeightValue, 255));
if (pa.WeightScalar != 255)
data.AddLine(GetInvalid(LStatIncorrectWeightValue));
data.AddLine(GetInvalid(StatIncorrectWeightValue, 255));
}
// No way to mutate the display height scalar value. Must match!
if (pa.HeightScalar != pa.Scale)
data.AddLine(GetInvalid(LStatIncorrectHeightCopy, CheckIdentifier.Encounter));
data.AddLine(GetInvalid(CheckIdentifier.Encounter, StatIncorrectHeightCopy));
}
private static void CheckLearnset(LegalityAnalysis data, PA8 pa)
@ -188,7 +188,7 @@ private void VerifyTutorMoveIndex(LegalityAnalysis data, PA8 pa, int i, IPermitR
if (permit.IsRecordPermitted(i))
return; // If it has been legally purchased, then any mastery state is legal.
data.AddLine(GetInvalid(string.Format(LMoveShopPurchaseInvalid_0, ParseSettings.MoveStrings[permit.RecordPermitIndexes[i]])));
data.AddLine(GetInvalid(MoveShopPurchaseInvalid_0, permit.RecordPermitIndexes[i]));
return;
}
@ -204,9 +204,9 @@ private void VerifyTutorMoveIndex(LegalityAnalysis data, PA8 pa, int i, IPermitR
if (data.EncounterMatch is (IMoveset m and IMasteryInitialMoveShop8) && m.Moves.Contains(move))
return; // Previously checked.
if (!permit.IsRecordPermitted(i))
data.AddLine(GetInvalid(string.Format(LMoveShopMasterInvalid_0, ParseSettings.MoveStrings[move])));
data.AddLine(GetInvalid(MoveShopMasterInvalid_0, move));
else if (!CanLearnMoveByLevelUp(data, pa, i, moves))
data.AddLine(GetInvalid(string.Format(LMoveShopMasterNotLearned_0, ParseSettings.MoveStrings[move])));
data.AddLine(GetInvalid(MoveShopMasterNotLearned_0, move));
}
private static bool CanLearnMoveByLevelUp(LegalityAnalysis data, PA8 pa, int i, ReadOnlySpan<ushort> moves)
@ -229,12 +229,12 @@ private void VerifyAlphaMove(LegalityAnalysis data, PA8 pa, ushort alphaMove, IP
{
if (!pa.IsAlpha || data.EncounterMatch is EncounterSlot8a { Type: SlotType8a.Landmark })
{
data.AddLine(GetInvalid(LMoveShopAlphaMoveShouldBeZero));
data.AddLine(GetInvalid(MoveShopAlphaMoveShouldBeZero));
return;
}
if (!CanMasterMoveFromMoveShop(alphaMove, permit))
{
data.AddLine(GetInvalid(LMoveShopAlphaMoveShouldBeOther));
data.AddLine(GetInvalid(MoveShopAlphaMoveShouldBeOther));
return;
}
@ -242,7 +242,7 @@ private void VerifyAlphaMove(LegalityAnalysis data, PA8 pa, ushort alphaMove, IP
var masteredIndex = permit.RecordPermitIndexes.IndexOf(alphaMove);
// Index is already >= 0, implicitly via the above call not returning false.
if (!pa.GetMasteredRecordFlag(masteredIndex))
data.AddLine(GetInvalid(LMoveShopAlphaMoveShouldBeMastered));
data.AddLine(GetInvalid(MoveShopAlphaMoveShouldBeMastered_0, alphaMove));
}
private void VerifyAlphaMoveZero(LegalityAnalysis data)
@ -256,7 +256,7 @@ private void VerifyAlphaMoveZero(LegalityAnalysis data)
var pi = PersonalTable.LA.GetFormEntry(enc.Species, enc.Form);
if (!pi.HasMoveShop) // must have had a tutor flag
data.AddLine(GetInvalid(LMoveShopAlphaMoveShouldBeOther));
data.AddLine(GetInvalid(MoveShopAlphaMoveShouldBeOther));
}
private static bool CanMasterMoveFromMoveShop(ushort move, IPermitRecord permit)

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -17,12 +17,12 @@ public override void Verify(LegalityAnalysis data)
{
if (!IsMetLevelMatchEncounter(gift, pk))
{
data.AddLine(GetInvalid(LLevelMetGift));
data.AddLine(GetInvalid(LevelMetGift));
return;
}
if (gift.Level > pk.CurrentLevel)
{
data.AddLine(GetInvalid(LLevelMetGiftFail));
data.AddLine(GetInvalid(LevelMetGiftFail, gift.Level));
return;
}
}
@ -31,7 +31,7 @@ public override void Verify(LegalityAnalysis data)
{
if (pk.CurrentLevel != enc.LevelMin)
{
data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, enc.LevelMin)));
data.AddLine(GetInvalid(EggFMetLevel_0, enc.LevelMin));
return;
}
@ -39,7 +39,7 @@ public override void Verify(LegalityAnalysis data)
? 125 // Gen2 Dizzy Punch gifts always have 125 EXP, even if it's more than the Lv5 exp required.
: Experience.GetEXP(enc.LevelMin, data.PersonalInfo.EXPGrowth);
if (reqEXP != pk.EXP)
data.AddLine(GetInvalid(LEggEXP));
data.AddLine(GetInvalid(EggEXP, reqEXP));
return;
}
@ -48,15 +48,15 @@ public override void Verify(LegalityAnalysis data)
{
var expect = Experience.GetEXP(100, data.PersonalInfo.EXPGrowth);
if (pk.EXP != expect)
data.AddLine(GetInvalid(LLevelEXPTooHigh));
data.AddLine(GetInvalid(Identifier, LevelEXPTooHigh, expect));
}
if (lvl < pk.MetLevel)
data.AddLine(GetInvalid(LLevelMetBelow));
data.AddLine(GetInvalid(LevelMetBelow, lvl));
else if (!enc.IsWithinEncounterRange(pk) && lvl != 100 && pk.EXP == Experience.GetEXP(lvl, data.PersonalInfo.EXPGrowth))
data.AddLine(Get(LLevelEXPThreshold, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, LevelEXPThreshold));
else
data.AddLine(GetValid(LLevelMetSane));
data.AddLine(GetValid(LevelMetSane));
}
private static bool IsMetLevelMatchEncounter(MysteryGift gift, PKM pk)
@ -81,25 +81,21 @@ public void VerifyG1(LegalityAnalysis data)
if (pk.IsEgg)
{
if (pk.CurrentLevel != EncounterEgg2.Level)
data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, EncounterEgg2.Level)));
data.AddLine(GetInvalid(EggFMetLevel_0, EncounterEgg2.Level));
return;
}
if (pk.MetLocation != 0) // crystal
{
var lvl = pk.CurrentLevel;
if (lvl < pk.MetLevel)
data.AddLine(GetInvalid(LLevelMetBelow));
data.AddLine(GetInvalid(LevelMetBelow, lvl));
}
if (IsTradeEvolutionRequired(data, enc))
{
// Pokémon has been traded illegally between games without evolving.
// Trade evolution species IDs for Gen1 are sequential dex numbers.
var names = ParseSettings.SpeciesStrings;
var species = enc.Species;
var evolved = names[species + 1];
var unevolved = names[species];
data.AddLine(GetInvalid(string.Format(LEvoTradeReqOutsider, unevolved, evolved)));
data.AddLine(GetInvalid(EvoTradeReqOutsider_0, enc.Species + 1u));
}
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.RibbonIndex;
namespace PKHeX.Core;
@ -25,13 +25,12 @@ public override void Verify(LegalityAnalysis data)
if (pk.IsEgg && pk is IRibbonSetAffixed a && a.AffixedRibbon != -1)
{
// Disallow affixed values on eggs.
var affix = (RibbonIndex)a.AffixedRibbon;
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, GetRibbonNameSafe(affix))));
data.AddLine(GetInvalid(RibbonMarkingAffixed_0, (ushort)(RibbonIndex)a.AffixedRibbon));
}
// Some encounters come with a fixed Mark, and we've not yet checked if it's missing.
if (data.EncounterMatch is IEncounterMarkExtra extra && extra.IsMissingExtraMark(pk, out var missing))
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(missing))));
data.AddLine(GetInvalid(RibbonMissing_0, (ushort)missing));
}
private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m)
@ -39,7 +38,7 @@ private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m)
for (var mark = MarkLunchtime; mark <= MarkSlump; mark++)
{
if (m.GetRibbon((int)mark))
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(mark))));
data.AddLine(GetInvalid(RibbonMarkingInvalid_0, (ushort)mark));
}
}
@ -54,14 +53,14 @@ private void VerifyMarksPresent(LegalityAnalysis data, IRibbonIndex m)
if (hasOne)
{
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(mark))));
data.AddLine(GetInvalid(RibbonMarkingInvalid_0, (ushort)mark));
return;
}
bool result = MarkRules.IsEncounterMarkValid(mark, data.Entity, data.EncounterMatch);
if (!result)
{
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(mark))));
data.AddLine(GetInvalid(RibbonMarkingInvalid_0, (ushort)mark));
return;
}
@ -69,14 +68,6 @@ private void VerifyMarksPresent(LegalityAnalysis data, IRibbonIndex m)
}
}
private static string GetRibbonNameSafe(RibbonIndex index)
{
if (index >= MAX_COUNT)
return index.ToString();
var expect = $"Ribbon{index}";
return RibbonStrings.GetName(expect);
}
private void VerifyAffixedRibbonMark(LegalityAnalysis data, IRibbonIndex m)
{
if (m is not IRibbonSetAffixed a)
@ -90,7 +81,7 @@ private void VerifyAffixedRibbonMark(LegalityAnalysis data, IRibbonIndex m)
var max = MarkRules.GetMaxAffixValue(data.Info.EvoChainsAllGens);
if ((sbyte)max == -1 || affix > max)
{
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, GetRibbonNameSafe(affix))));
data.AddLine(GetInvalid(RibbonMarkingAffixed_0, (ushort)affix));
return;
}
@ -114,7 +105,7 @@ private void VerifyShedinjaAffixed(LegalityAnalysis data, RibbonIndex affix, PKM
if (affix.IsEncounterMark8())
{
if (!MarkRules.IsEncounterMarkValid(affix, pk, enc))
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, GetRibbonNameSafe(affix))));
data.AddLine(GetInvalid(RibbonMarkingAffixed_0, (ushort)affix));
return;
}
@ -129,10 +120,9 @@ private void VerifyShedinjaAffixed(LegalityAnalysis data, RibbonIndex affix, PKM
clone.Species = (int) Species.Nincada;
var args = new RibbonVerifierArguments(clone, enc, data.Info.EvoChainsAllGens);
affix.Fix(args, true);
var name = GetRibbonNameSafe(affix);
bool invalid = RibbonVerifier.IsValidExtra(affix, args);
var severity = invalid ? Severity.Invalid : Severity.Fishy;
data.AddLine(Get(string.Format(LRibbonMarkingAffixedF_0, name), severity));
data.AddLine(Get(severity, RibbonMarkingAffixed_0, (ushort)affix));
}
private static bool IsMoveSetEvolvedShedinja(PKM pk)
@ -153,6 +143,6 @@ private void EnsureHasRibbon(LegalityAnalysis data, IRibbonIndex m, RibbonIndex
{
var hasRibbon = m.GetRibbonIndex(affix);
if (!hasRibbon)
data.AddLine(GetInvalid(string.Format(LRibbonMarkingAffixedF_0, GetRibbonNameSafe(affix))));
data.AddLine(GetInvalid(RibbonMarkingAffixed_0, (ushort)affix));
}
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.CheckIdentifier;
namespace PKHeX.Core;
@ -21,7 +21,7 @@ private void VerifyFavoriteMark(LegalityAnalysis data, PKM pk)
{
// Can only be toggled on in LGP/E, and is retained via transfer to HOME and into other games.
if (pk is IFavorite { IsFavorite: true } && !data.Info.EvoChainsAllGens.HasVisitedLGPE)
data.AddLine(GetInvalid(LFavoriteMarkingUnavailable));
data.AddLine(GetInvalid(FavoriteMarkingUnavailable));
}
private void VerifyMarkValue(LegalityAnalysis data, PKM pk)
@ -47,14 +47,14 @@ private void VerifyMarkValueDual(LegalityAnalysis data, IAppliedMarkings7 pk, us
if (mv == 0)
return;
if (mv > Dual6)
data.AddLine(GetInvalid(LMarkValueUnusedBitsPresent));
data.AddLine(GetInvalid(MarkValueUnusedBitsPresent));
var count = pk.MarkingCount;
for (int i = 0; i < count; i++)
{
var value = pk.GetMarking(i);
if (value is not (0 or MarkingColor.Blue or MarkingColor.Pink))
data.AddLine(GetInvalid(string.Format(LMarkValueOutOfRange_0, i)));
data.AddLine(GetInvalid(MarkValueOutOfRange_0, (ushort)i));
}
}
@ -63,7 +63,7 @@ private void VerifyMarkValueSingle(LegalityAnalysis data, IAppliedMarkings3 pk,
if (mv == 0)
return;
if (!IsMarkValueValid3456(pk, mv))
data.AddLine(GetInvalid(LMarkValueUnusedBitsPresent));
data.AddLine(GetInvalid(MarkValueUnusedBitsPresent));
}
private static bool IsMarkValueValid3456(IAppliedMarkings3 pk, int value)

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -22,18 +22,18 @@ private void VerifyMedalsRegular(LegalityAnalysis data)
var Info = data.Info;
uint value = train.SuperTrainBitFlags;
if ((value & 3) != 0) // 2 unused flags
data.AddLine(GetInvalid(LSuperUnused));
data.AddLine(GetInvalid(SuperUnused));
int TrainCount = train.SuperTrainingMedalCount();
if (pk.IsEgg)
{
// Can't have any super training data as an egg.
if (TrainCount > 0)
data.AddLine(GetInvalid(LSuperEgg));
data.AddLine(GetInvalid(SuperEgg));
if (train.SecretSuperTrainingUnlocked)
data.AddLine(GetInvalid(LSuperNoUnlocked));
data.AddLine(GetInvalid(SuperNoUnlocked));
if (train.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(LSuperNoComplete));
data.AddLine(GetInvalid(SuperNoComplete));
return;
}
@ -41,11 +41,11 @@ private void VerifyMedalsRegular(LegalityAnalysis data)
{
// Can't have any super training data if it never visited Gen6.
if (TrainCount > 0)
data.AddLine(GetInvalid(LSuperUnavailable));
data.AddLine(GetInvalid(SuperUnavailable));
if (train.SecretSuperTrainingUnlocked)
data.AddLine(GetInvalid(LSuperNoUnlocked));
data.AddLine(GetInvalid(SuperNoUnlocked));
if (train.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(LSuperNoComplete));
data.AddLine(GetInvalid(SuperNoComplete));
return;
}
@ -53,15 +53,15 @@ private void VerifyMedalsRegular(LegalityAnalysis data)
{
// Gen6->Gen7 transfer wipes the two Secret flags.
if (train.SecretSuperTrainingUnlocked)
data.AddLine(GetInvalid(LSuperNoUnlocked));
data.AddLine(GetInvalid(SuperNoUnlocked));
if (train.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(LSuperNoComplete));
data.AddLine(GetInvalid(SuperNoComplete));
return;
}
// Only reach here if Format==6.
if (TrainCount == 30 ^ train.SecretSuperTrainingComplete)
data.AddLine(GetInvalid(LSuperComplete));
data.AddLine(GetInvalid(SuperComplete));
}
private void VerifyMedalsEvent(LegalityAnalysis data)
@ -69,6 +69,6 @@ private void VerifyMedalsEvent(LegalityAnalysis data)
var pk = data.Entity;
byte value = pk.Data[0x3A];
if (value != 0)
data.AddLine(GetInvalid(LSuperDistro));
data.AddLine(GetInvalid(SuperDistro));
}
}

View File

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.MemoryPermissions;
using static PKHeX.Core.EntityContext;
@ -85,7 +85,7 @@ private void VerifyHTLanguage(LegalityAnalysis data, MemorySource source)
if (pk is not IHandlerLanguage h)
return;
if (!GetIsHTLanguageValid(data.EncounterMatch, pk, h.HandlingTrainerLanguage, source))
data.AddLine(GetInvalid(LMemoryHTLanguage));
data.AddLine(GetInvalid(MemoryHTLanguage));
}
private static bool GetIsHTLanguageValid(IEncounterTemplate enc, PKM pk, byte language, MemorySource source)
@ -142,16 +142,16 @@ private CheckResult VerifyCommonMemory(PKM pk, int handler, LegalInfo info, Memo
return VerifyMemoryHM6(info, mem, memory, hmIndex);
if (mem.IsInvalidGeneralLocationMemoryValue(memory.MemoryID, memory.Variable, info.EncounterMatch, pk))
return GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler));
return GetInvalid(MemoryArgBadLocation_H, memory.Handler);
if (mem.IsInvalidMiscMemory(memory.MemoryID, memory.Variable, (Species)pk.Species, pk.Version, handler))
return GetInvalid(string.Format(LMemoryArgBadID, memory.Handler));
return GetInvalid(MemoryArgBadID_H, memory.Handler);
switch (memory.MemoryID)
{
case 19 when pk.Species is (int)Species.Urshifu && memory.Variable is not 34: // tall building is the only location for evolving Urshifu
case 19 when pk.Species is (int)Species.Runerigus && memory.Variable is not 72: // vast field is the only location for evolving Runerigus
return GetInvalid(string.Format(LMemoryArgBadLocation, memory.Handler));
return GetInvalid(MemoryArgBadLocation_H, memory.Handler);
// {0} saw {2} carrying {1} on its back. {4} that {3}.
case 21 when mem.Context != Gen6 || !PersonalTable.AO.GetFormEntry(memory.Variable, 0).GetIsLearnHM(2): // Fly
@ -170,7 +170,7 @@ private CheckResult VerifyCommonMemory(PKM pk, int handler, LegalInfo info, Memo
case 71 when !GetCanDynamaxTrainer(memory.Variable, 8, handler == 0 ? pk.Version : GameVersion.Any):
// {0} battled {2} and Dynamaxed upon {1}s instruction. {4} that {3}.
case 72 when !PersonalTable.SWSH.IsSpeciesInGame(memory.Variable):
return GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler));
return GetInvalid(MemoryArgBadSpecies_H1, memory.Handler, memory.Variable);
// Move
// {0} studied about how to use {2} in a Box, thinking about {1}. {4} that {3}.
@ -181,23 +181,23 @@ private CheckResult VerifyCommonMemory(PKM pk, int handler, LegalInfo info, Memo
// Species
// With {1}, {0} went fishing, and they caught {2}. {4} that {3}.
case 7 when !GetCanFishSpecies(memory.Variable, mem.Context, handler == 0 ? pk.Version : GameVersion.Any):
return GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler));
return GetInvalid(MemoryArgBadSpecies_H1, memory.Handler, memory.Variable);
// {0} saw {1} paying attention to {2}. {4} that {3}.
// {0} fought hard until it had to use Struggle when it battled at {1}s side against {2}. {4} that {3}.
// {0} was taken to a Pokémon Nursery by {1} and left with {2}. {4} that {3}.
case 9 or 60 or 75 when mem.Context == Gen8 && !PersonalTable.SWSH.IsSpeciesInGame(memory.Variable):
return GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler));
return GetInvalid(MemoryArgBadSpecies_H1, memory.Handler, memory.Variable);
// {0} had a great chat about {1} with the {2} that it was in a Box with. {4} that {3}.
// {0} became good friends with the {2} in a Box, practiced moves with it, and talked about the day that {0} would be praised by {1}. {4} that {3}.
// {0} got in a fight with the {2} that it was in a Box with about {1}. {4} that {3}.
case 82 or 83 or 87 when !PersonalTable.SWSH.IsSpeciesInGame(memory.Variable):
return GetInvalid(string.Format(LMemoryArgBadSpecies, memory.Handler));
return GetInvalid(MemoryArgBadSpecies_H1, memory.Handler, memory.Variable);
// {0} had a very hard training session with {1}. {4} that {3}.
case 53 when mem.Context == Gen8 && pk is IHyperTrain t && !t.IsHyperTrained():
return GetInvalid(string.Format(LMemoryArgBadID, memory.Handler));
return GetInvalid(MemoryArgBadID_H, memory.Handler);
// Item
// {0} went to a Pokémon Center with {1} to buy {2}. {4} that {3}.
@ -215,7 +215,7 @@ private CheckResult VerifyCommonMemory(PKM pk, int handler, LegalInfo info, Memo
// {0} was worried if {1} was looking for the {2} that it was holding in a Box. {4} that {3}.
// When {0} was in a Box, it thought about the reason why {1} had it hold the {2}. {4} that {3}.
case 84 or 88 when !Legal.HeldItems_SWSH.Contains(memory.Variable) || pk.IsEgg:
return GetInvalid(string.Format(LMemoryArgBadItem, memory.Handler));
return GetInvalid(Identifier, MemoryArgBadItem_H1, memory.Handler, memory.Variable);
}
return VerifyCommonMemoryEtc(memory, mem);
@ -244,22 +244,25 @@ private CheckResult VerifyMemoryHM6(LegalInfo info, MemoryContext mem, MemoryVar
return BadSpeciesMove(memory.Handler);
}
private CheckResult BadSpeciesMove(string handler) => GetInvalid(string.Format(LMemoryArgBadMove, handler));
private CheckResult BadSpeciesMove(byte handler) => GetInvalid(MemoryArgBadMove_H1, handler);
private CheckResult VerifyCommonMemoryEtc(MemoryVariableSet memory, MemoryContext context)
{
if (!context.CanHaveIntensity(memory.MemoryID, memory.Intensity))
{
var min = context.GetMinimumIntensity(memory.MemoryID);
return GetInvalid(string.Format(LMemoryIndexIntensityMin, memory.Handler, min));
return GetInvalid(Identifier, MemoryIndexIntensityMin_H1, memory.Handler, min);
}
if (!context.CanHaveFeeling(memory.MemoryID, memory.Feeling, memory.Variable))
return GetInvalid(string.Format(LMemoryFeelInvalid, memory.Handler));
return GetInvalid(MemoryFeelInvalid_H, memory.Handler);
return GetValid(string.Format(LMemoryF_0_Valid, memory.Handler));
return GetValid(MemoryValid_H, memory.Handler);
}
private const ushort L_XOT = 0; // Original Trainer Memory
private const ushort L_XHT = 1; // Handling Trainer Memory
/// <summary>
/// Used for enforcing a fixed memory detail.
/// </summary>
@ -272,19 +275,19 @@ private void VerifyOTMemoryIs(LegalityAnalysis data, byte m, byte i, ushort t, b
{
var pk = (ITrainerMemories)data.Entity;
if (pk.OriginalTrainerMemory != m)
data.AddLine(GetInvalid(string.Format(LMemoryIndexID, L_XOT, m)));
data.AddLine(GetInvalid(MemoryIndexID_H1, L_XOT, m));
if (pk.OriginalTrainerMemoryIntensity != i)
data.AddLine(GetInvalid(string.Format(LMemoryIndexIntensity, L_XOT, i)));
data.AddLine(GetInvalid(MemoryIndexIntensity_H1, L_XOT, i));
if (pk.OriginalTrainerMemoryVariable != t)
data.AddLine(GetInvalid(string.Format(LMemoryIndexVar, L_XOT, t)));
data.AddLine(GetInvalid(MemoryIndexVar_H1, L_XOT, t));
if (pk.OriginalTrainerMemoryFeeling != f)
data.AddLine(GetInvalid(string.Format(LMemoryIndexFeel, L_XOT, f)));
data.AddLine(GetInvalid(MemoryIndexFeel_H1, L_XOT, f));
}
private void VerifyHTMemoryNone(LegalityAnalysis data, ITrainerMemories pk)
{
if (pk.HandlingTrainerMemory != 0 || pk.HandlingTrainerMemoryVariable != 0 || pk.HandlingTrainerMemoryIntensity != 0 || pk.HandlingTrainerMemoryFeeling != 0)
data.AddLine(GetInvalid(string.Format(LMemoryCleared, L_XHT)));
data.AddLine(GetInvalid(MemoryCleared_H, L_XHT));
}
private void VerifyOTMemory(LegalityAnalysis data)
@ -339,37 +342,37 @@ private void VerifyOTMemory(LegalityAnalysis data)
// Bounds checking
var mc = Memories.GetContext(context);
if (!mc.CanObtainMemoryOT(pk.Version, memory))
data.AddLine(GetInvalid(string.Format(LMemoryArgBadID, L_XOT)));
data.AddLine(GetInvalid(MemoryArgBadID_H, L_XOT));
// Verify memory if specific to OT
switch (memory)
{
// No Memory
case 0: // SW/SH trades don't set HT memories immediately, which is hilarious.
data.AddLine(Get(LMemoryMissingOT, mc.Context == Gen8 ? Severity.Fishy : Severity.Invalid));
data.AddLine(Get(mc.Context == Gen8 ? Severity.Fishy : Severity.Invalid, MemoryMissingOT));
VerifyOTMemoryIs(data, 0, 0, 0, 0);
return;
// {0} hatched from an Egg and saw {1} for the first time at... {2}. {4} that {3}.
case 2 when !enc.IsEgg:
data.AddLine(GetInvalid(string.Format(LMemoryArgBadHatch, L_XOT)));
data.AddLine(GetInvalid(MemoryArgBadHatch_H, L_XOT));
break;
// {0} became {1}s friend when it arrived via Link Trade at... {2}. {4} that {3}.
case 4 when mc.Context == Gen6: // Gen8 applies this memory erroneously
data.AddLine(GetInvalid(string.Format(LMemoryArgBadOTEgg, L_XOT)));
data.AddLine(GetInvalid(MemoryArgBadOTEgg_H, L_XOT));
return;
// {0} went to the Pokémon Center in {2} with {1} and had its tired body healed there. {4} that {3}.
case 6 when !mc.HasPokeCenter(pk.Version, mem.OriginalTrainerMemoryVariable):
data.AddLine(GetInvalid(string.Format(LMemoryArgBadLocation, L_XOT)));
data.AddLine(GetInvalid(MemoryArgBadLocation_H, L_XOT));
return;
// {0} was with {1} when {1} caught {2}. {4} that {3}.
case 14:
var result = GetCanBeCaptured(mem.OriginalTrainerMemoryVariable, mc.Context, pk.Version) // Any Game in the Handling Trainer's generation
? GetValid(string.Format(LMemoryArgSpecies, L_XOT))
: GetInvalid(string.Format(LMemoryArgBadSpecies, L_XOT));
? GetValid(MemoryArgSpecies_H, L_XOT)
: GetInvalid(MemoryArgBadSpecies_H1, L_XOT, mem.OriginalTrainerMemoryVariable);
data.AddLine(result);
return;
}
@ -426,7 +429,7 @@ private void VerifyHTMemory(LegalityAnalysis data, EntityContext memoryGen)
// Bounds checking
var mc = Memories.GetContext(memoryGen);
if (!mc.CanObtainMemoryHT(pk.Version, memory))
data.AddLine(GetInvalid(string.Format(LMemoryArgBadID, L_XHT)));
data.AddLine(GetInvalid(MemoryArgBadID_H, L_XHT));
// Verify memory if specific to HT
switch (memory)
@ -440,30 +443,30 @@ private void VerifyHTMemory(LegalityAnalysis data, EntityContext memoryGen)
_ => Severity.Invalid,
};
if (severity != Severity.Valid)
data.AddLine(Get(LMemoryMissingHT, severity));
data.AddLine(Get(severity, MemoryMissingHT));
VerifyHTMemoryNone(data, mem);
return;
// {0} met {1} at... {2}. {1} threw a Poké Ball at it, and they started to travel together. {4} that {3}.
case 1:
data.AddLine(GetInvalid(string.Format(LMemoryArgBadCatch, L_XHT)));
data.AddLine(GetInvalid(MemoryArgBadCatch_H, L_XHT));
return;
// {0} hatched from an Egg and saw {1} for the first time at... {2}. {4} that {3}.
case 2:
data.AddLine(GetInvalid(string.Format(LMemoryArgBadHatch, L_XHT)));
data.AddLine(GetInvalid(MemoryArgBadHatch_H, L_XHT));
return;
// {0} went to the Pokémon Center in {2} with {1} and had its tired body healed there. {4} that {3}.
case 6 when !mc.HasPokeCenter(GameVersion.Any, mem.HandlingTrainerMemoryVariable):
data.AddLine(GetInvalid(string.Format(LMemoryArgBadLocation, L_XHT)));
data.AddLine(GetInvalid(MemoryArgBadLocation_H, L_XHT));
return;
// {0} was with {1} when {1} caught {2}. {4} that {3}.
case 14:
var result = GetCanBeCaptured(mem.HandlingTrainerMemoryVariable, mc.Context, GameVersion.Any) // Any Game in the Handling Trainer's generation
? GetValid(string.Format(LMemoryArgSpecies, L_XHT))
: GetInvalid(string.Format(LMemoryArgBadSpecies, L_XHT));
? GetValid(MemoryArgSpecies_H, L_XHT)
: GetInvalid(MemoryArgBadSpecies_H1, L_XHT, mem.HandlingTrainerMemoryVariable);
data.AddLine(result);
return;
}
@ -492,12 +495,12 @@ private void VerifyHTMemoryTransferTo7(LegalityAnalysis data, PKM pk, LegalInfo
return;
if (mem.HandlingTrainerMemory != 4)
data.AddLine(Severity.Invalid, LMemoryIndexLinkHT, CheckIdentifier.Memory);
data.AddLine(GetInvalid(MemoryIndexLinkHT, L_XHT, 4));
if (mem.HandlingTrainerMemoryVariable != 0)
data.AddLine(Severity.Invalid, LMemoryIndexArgHT, CheckIdentifier.Memory);
data.AddLine(GetInvalid(MemoryIndexArgHT, L_XHT, 0));
if (mem.HandlingTrainerMemoryIntensity != 1)
data.AddLine(Severity.Invalid, LMemoryIndexIntensityHT1, CheckIdentifier.Memory);
if (mem.HandlingTrainerMemoryFeeling > 10)
data.AddLine(Severity.Invalid, LMemoryIndexFeelHT09, CheckIdentifier.Memory);
data.AddLine(GetInvalid(MemoryIndexIntensityHT1, L_XHT, 1));
if (mem.HandlingTrainerMemoryFeeling >= 10)
data.AddLine(GetInvalid(MemoryIndexFeelHTLEQ9, L_XHT));
}
}

View File

@ -67,7 +67,7 @@ public static void SetMaxContestStats(this PKM pk, IEncounterTemplate enc, Evolu
_ => h.HasVisitedBDSP ? CorrelateSheen : None, // BD/SP Contests
};
public static int CalculateMaximumSheen(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial, bool pokeBlock3)
public static byte CalculateMaximumSheen(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial, bool pokeBlock3)
{
if (s.IsAnyContestStatMax())
return MaxContestStat;
@ -86,10 +86,10 @@ public static int CalculateMaximumSheen(IContestStatsReadOnly s, Nature nature,
return 59;
// Can get trash poffins by burning and spilling on purpose.
return Math.Min(MaxContestStat, avg * HighestFeelPoffin8b);
return (byte)Math.Min(MaxContestStat, avg * HighestFeelPoffin8b);
}
public static int CalculateMinimumSheen(IContestStatsReadOnly s, IContestStatsReadOnly initial, INature pk, ContestStatGrantingSheen method) => method switch
public static byte CalculateMinimumSheen(IContestStatsReadOnly s, IContestStatsReadOnly initial, INature pk, ContestStatGrantingSheen method) => method switch
{
ContestStatGrantingSheen.Gen8b => CalculateMinimumSheen8b(s, pk.Nature, initial),
ContestStatGrantingSheen.Gen3 => CalculateMinimumSheen3(s, pk.Nature, initial),
@ -98,7 +98,7 @@ public static int CalculateMaximumSheen(IContestStatsReadOnly s, Nature nature,
};
// BD/SP has a slightly better stat:sheen ratio than Gen4; prefer if it has visited.
public static int CalculateMinimumSheen8b(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
public static byte CalculateMinimumSheen8b(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
{
if (s.IsContestEqual(initial))
return initial.ContestSheen;
@ -111,10 +111,10 @@ public static int CalculateMinimumSheen8b(IContestStatsReadOnly s, Nature nature
avg = Math.Min(rawAvg, avg); // be generous
avg = (BestSheenStat8b * avg) / MaxContestStat;
return Math.Clamp(avg, LowestFeelPoffin8b, BestSheenStat8b);
return (byte)Math.Clamp(avg, LowestFeelPoffin8b, BestSheenStat8b);
}
public static int CalculateMinimumSheen3(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
public static byte CalculateMinimumSheen3(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
{
if (s.IsContestEqual(initial))
return initial.ContestSheen;
@ -127,10 +127,10 @@ public static int CalculateMinimumSheen3(IContestStatsReadOnly s, Nature nature,
avg = Math.Min(rawAvg, avg); // be generous
avg = (BestSheenStat3 * avg) / MaxContestStat;
return Math.Clamp(avg, LowestFeelBlock3, BestSheenStat3);
return (byte)Math.Clamp(avg, LowestFeelBlock3, BestSheenStat3);
}
public static int CalculateMinimumSheen4(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
public static byte CalculateMinimumSheen4(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
{
if (s.IsContestEqual(initial))
return initial.ContestSheen;
@ -142,10 +142,10 @@ public static int CalculateMinimumSheen4(IContestStatsReadOnly s, Nature nature,
var avg = Math.Max(1, (byte)nature % 6 == 0 ? rawAvg : GetAverageFeel(s, nature, initial));
avg = Math.Min(rawAvg, avg); // be generous
return Math.Clamp(avg, LowestFeelPoffin4, MaxContestStat);
return (byte)Math.Clamp(avg, LowestFeelPoffin4, MaxContestStat);
}
private static int CalculateMaximumSheen3(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
private static byte CalculateMaximumSheen3(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)
{
// By using Enigma and Lansat and a 25 +1/-1, can get a +9/+19s at minimum RPM
// By using Strib, Chilan, Niniku, or Topo, can get a black +2/2/2 & 83 block (6:83) at minimum RPM.
@ -164,7 +164,7 @@ private static int CalculateMaximumSheen3(IContestStatsReadOnly s, Nature nature
// Prefer the bad-black-block correlation if more than 3 stats have gains >= 2.
var permit = has3 ? (sum * 83 / 6) : (sum * 19 / 9);
return Math.Clamp(permit, LowestFeelBlock3, MaxContestStat);
return (byte)Math.Clamp(permit, LowestFeelBlock3, MaxContestStat);
}
private static int GetAverageFeel(IContestStatsReadOnly s, Nature nature, IContestStatsReadOnly initial)

View File

@ -1,6 +1,5 @@
using System;
using System.Text;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.CheckIdentifier;
namespace PKHeX.Core;
@ -23,36 +22,36 @@ public override void Verify(LegalityAnalysis data)
// No egg have contest stats from the encounter.
if (pk is IContestStatsReadOnly s && s.HasContestStats())
data.AddLine(GetInvalid(LEggContest, Egg));
data.AddLine(GetInvalid(Egg, EggContest));
// Cannot transfer eggs across contexts (must be hatched).
var e = data.EncounterOriginal;
if (e.Context != pk.Context)
data.AddLine(GetInvalid(LTransferEggVersion, Egg));
data.AddLine(GetInvalid(Egg, TransferEggVersion));
switch (pk)
{
// Side Game: No Eggs
case SK2 or CK3 or XK3 or BK4 or RK4 when e.Context == pk.Context:
data.AddLine(GetInvalid(LTransferEggVersion, Egg));
data.AddLine(GetInvalid(Egg, TransferEggVersion));
break;
// All Eggs are Japanese and flagged specially for localized string
case PK3 when pk.Language != 1:
data.AddLine(GetInvalid(string.Format(LOTLanguage, LanguageID.Japanese, (LanguageID)pk.Language), Egg));
data.AddLine(GetInvalid(Egg, OTLanguageShouldBe_0, (byte)LanguageID.Japanese));
break;
// Cannot obtain Shiny Leaf or Pokeathlon Stats as Egg
case PK4 pk4:
if (pk4.ShinyLeaf != 0)
data.AddLine(GetInvalid(LEggShinyLeaf, Egg));
data.AddLine(GetInvalid(Egg, EggShinyLeaf));
if (pk4.PokeathlonStat != 0)
data.AddLine(GetInvalid(LEggPokeathlon, Egg));
data.AddLine(GetInvalid(Egg, EggPokeathlon));
break;
}
if (pk is IHomeTrack { HasTracker: true })
data.AddLine(GetInvalid(LTransferTrackerShouldBeZero));
data.AddLine(GetInvalid(TransferTrackerShouldBeZero));
}
switch (pk)
@ -88,7 +87,7 @@ public override void Verify(LegalityAnalysis data)
if (s64.TryGetSeed(pk, out var seed))
data.Info.PIDIV = new PIDIV(PIDType.Xoroshiro, seed);
if (enc is IMasteryInitialMoveShop8 m && !m.IsForcedMasteryCorrect(pk))
data.AddLine(GetInvalid(LEncMasteryInitial));
data.AddLine(GetInvalid(EncMasteryInitial));
}
VerifyMiscFatefulEncounter(data);
@ -111,7 +110,7 @@ private void VerifyCorrelation8b(LegalityAnalysis data, IStaticCorrelation8b s8b
};
if (!valid)
data.AddLine(GetInvalid(LPIDTypeMismatch));
data.AddLine(GetInvalid(PIDTypeMismatch));
}
private void VerifyCorrelation8(LegalityAnalysis data, IOverworldCorrelation8 z, PKM pk)
@ -132,7 +131,7 @@ private void VerifyCorrelation8(LegalityAnalysis data, IOverworldCorrelation8 z,
};
if (!valid)
data.AddLine(GetInvalid(LPIDTypeMismatch));
data.AddLine(GetInvalid(PIDTypeMismatch));
}
private void VerifyServerDate2000(LegalityAnalysis data, PKM pk, IEncounterable enc, IEncounterServerDate date)
@ -144,18 +143,18 @@ private void VerifyServerDate2000(LegalityAnalysis data, PKM pk, IEncounterable
if (enc is WB8 { IsDateLockJapanese: true } or WA8 { IsDateLockJapanese: true })
{
if (actualDay < new DateOnly(2022, 5, 20) && pk.Language != (int)LanguageID.Japanese)
data.AddLine(GetInvalid(LDateOutsideDistributionWindow));
data.AddLine(GetInvalid(DateOutsideDistributionWindow));
}
var result = date.IsWithinDistributionWindow(actualDay);
if (result == EncounterServerDateCheck.Invalid)
data.AddLine(GetInvalid(LDateOutsideDistributionWindow));
data.AddLine(GetInvalid(DateOutsideDistributionWindow));
}
private void VerifyStats7(LegalityAnalysis data, PK7 pk7)
{
if (pk7.ResortEventStatus >= ResortEventState.MAX)
data.AddLine(GetInvalid(LTransferBad));
data.AddLine(GetInvalid(TransferBad));
}
private void VerifyMiscScaleValues(LegalityAnalysis data, PKM pk, IEncounterTemplate enc)
@ -168,20 +167,20 @@ private void VerifyMiscScaleValues(LegalityAnalysis data, PKM pk, IEncounterTemp
{
// Gen1-7 can have 0-0 if kept in PLA before HOME 3.0
if (s2 is { HeightScalar: 0, WeightScalar: 0 } && !data.Info.EvoChainsAllGens.HasVisitedPLA && enc is not IPogoSlot)
data.AddLine(Get(LStatInvalidHeightWeight, Severity.Invalid, Encounter));
data.AddLine(Get(Encounter, Severity.Invalid, StatInvalidHeightWeight));
}
else if (CheckHeightWeightOdds(data.EncounterMatch))
{
if (s2 is { HeightScalar: 0, WeightScalar: 0 })
{
if (ParseSettings.Settings.HOMETransfer.ZeroHeightWeight != Severity.Valid)
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, Encounter));
data.AddLine(Get(Encounter, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, StatInvalidHeightWeight));
}
}
// Check for Scale
if (pk is IScaledSize3 s3 && IsHeightScaleMatchRequired(pk) && s2.HeightScalar != s3.Scale)
data.AddLine(GetInvalid(LStatIncorrectHeightValue));
data.AddLine(GetInvalid(StatIncorrectHeightValue));
}
private void VerifyIsMovesetAllowed(LegalityAnalysis data, SK2 sk2)
@ -220,18 +219,18 @@ private static void VerifyStats5(LegalityAnalysis data, PK5 pk5)
// Cannot participate in Pokestar Studios as Egg
if (pk5.IsEgg && pk5.PokeStarFame != 0)
data.AddLine(GetInvalid(LEggShinyPokeStar, Egg));
data.AddLine(GetInvalid(Egg, EggShinyPokeStar));
// Ensure NSparkle is only present on N's encounters.
if (enc is EncounterStatic5N)
{
if (!pk5.NSparkle)
data.AddLine(GetInvalid(LG5SparkleRequired, Fateful));
data.AddLine(GetInvalid(Fateful, G5SparkleRequired));
}
else
{
if (pk5.NSparkle)
data.AddLine(GetInvalid(LG5SparkleInvalid, Fateful));
data.AddLine(GetInvalid(Fateful, G5SparkleInvalid));
}
}
@ -248,35 +247,35 @@ private void VerifyStats9(LegalityAnalysis data, PK9 pk9)
VerifyTechRecordSV(data, pk9);
if (!pk9.IsBattleVersionValid(data.Info.EvoChainsAllGens))
data.AddLine(GetInvalid(LStatBattleVersionInvalid));
data.AddLine(GetInvalid(StatBattleVersionInvalid));
if (!IsObedienceLevelValid(pk9, pk9.ObedienceLevel, pk9.MetLevel))
data.AddLine(GetInvalid(LTransferObedienceLevel));
data.AddLine(GetInvalid(TransferObedienceLevel));
if (pk9.IsEgg)
{
if (pk9.TeraTypeOverride != (MoveType)TeraTypeUtil.OverrideNone)
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
}
else if (pk9.Species == (int)Species.Terapagos)
{
if (!TeraTypeUtil.IsValidTerapagos((byte)pk9.TeraTypeOverride))
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
}
else if (pk9.Species == (int)Species.Ogerpon)
{
if (!TeraTypeUtil.IsValidOgerpon((byte)pk9.TeraTypeOverride, pk9.Form))
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
}
else
{
if (!TeraTypeUtil.IsValid((byte)pk9.TeraTypeOriginal))
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
}
var enc = data.EncounterOriginal;
if (enc is EncounterEgg9 g)
{
if (!Tera9RNG.IsMatchTeraTypePersonalEgg(g.Species, g.Form, (byte)pk9.TeraTypeOriginal))
data.AddLine(GetInvalid(LTeraTypeMismatch));
data.AddLine(GetInvalid(TeraTypeMismatch));
}
else if (enc is ITeraRaid9)
{
@ -286,15 +285,15 @@ private void VerifyStats9(LegalityAnalysis data, PK9 pk9)
else if (enc is not { Context: EntityContext.Gen9 } || pk9 is { GO_HOME: true })
{
if (pk9.TeraTypeOverride == (MoveType)TeraTypeUtil.OverrideNone)
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
else if (GetTeraImportMatch(data.Info.EvoChainsAllGens.Gen9, pk9.TeraTypeOriginal, enc) == -1)
data.AddLine(GetInvalid(LTeraTypeIncorrect));
data.AddLine(GetInvalid(TeraTypeIncorrect));
}
else if (enc is EncounterStatic9 { StarterBoxLegend: true })
{
// Ride legends cannot be traded or transferred.
if (pk9.CurrentHandler != 0 || pk9.Tracker != 0 || !pk9.IsUntraded)
data.AddLine(GetInvalid(LTransferBad));
data.AddLine(GetInvalid(TransferBad));
}
if (!Locations9.IsAccessiblePreDLC(pk9.MetLocation))
@ -309,7 +308,7 @@ private void VerifyStats9(LegalityAnalysis data, PK9 pk9)
// Safari and Sport are not obtainable in the base game.
// For the learnset restricted cases, we need to check if the ball is available too.
if (((BallUseLegality.WildPokeballs9PreDLC2 >> pk9.Ball) & 1) != 1)
data.AddLine(GetInvalid(LBallUnavailable));
data.AddLine(GetInvalid(BallUnavailable));
}
}
@ -372,11 +371,11 @@ private void VerifyMiscPokerus(LegalityAnalysis data)
var days = pk.PokerusDays;
bool strainValid = Pokerus.IsStrainValid(pk, data.Info.EncounterMatch, strain, days);
if (!strainValid)
data.AddLine(GetInvalid(string.Format(LPokerusStrainUnobtainable_0, strain)));
data.AddLine(GetInvalid(PokerusStrainUnobtainable_0, (ushort)strain));
bool daysValid = Pokerus.IsDurationValid(strain, days, out var max);
if (!daysValid)
data.AddLine(GetInvalid(string.Format(LPokerusDaysTooHigh_0, max)));
data.AddLine(GetInvalid(PokerusDaysLEQ_0, (ushort)max));
}
public void VerifyMiscG1(LegalityAnalysis data)
@ -397,7 +396,7 @@ public void VerifyMiscG1(LegalityAnalysis data)
_ => time is 1 or 2 or 3,
};
if (!valid)
data.AddLine(new CheckResult(Severity.Invalid, Encounter, LMetDetailTimeOfDay));
data.AddLine(GetInvalid(Encounter, MetDetailTimeOfDay));
}
return;
}
@ -414,16 +413,16 @@ private void VerifyMiscG1Types(LegalityAnalysis data, PK1 pk1)
// Can have any type combination of any species by using Conversion.
if (!PersonalTable1.TypeIDExists(pk1.Type1))
{
data.AddLine(GetInvalid(LG1TypePorygonFail1));
data.AddLine(GetInvalid(G1TypePorygonFail1));
}
if (!PersonalTable1.TypeIDExists(pk1.Type2))
{
data.AddLine(GetInvalid(LG1TypePorygonFail2));
data.AddLine(GetInvalid(G1TypePorygonFail2));
}
else // Both types exist, ensure a Gen1 species has this combination
{
var matchSpecies = PersonalTable.RB.IsValidTypeCombination(pk1);
var result = matchSpecies != -1 ? GetValid(LG1TypeMatchPorygon) : GetInvalid(LG1TypePorygonFail);
var result = matchSpecies != -1 ? GetValid(G1TypeMatchPorygon) : GetInvalid(G1TypePorygonFail);
data.AddLine(result);
}
}
@ -434,8 +433,8 @@ private void VerifyMiscG1Types(LegalityAnalysis data, PK1 pk1)
if (!match2 && ParseSettings.AllowGBStadium2)
match2 = (species is (int)Species.Magnemite or (int)Species.Magneton) && pk1.Type2 == 9; // Steel Magnemite via Stadium2
var first = match1 ? GetValid(LG1TypeMatch1) : GetInvalid(LG1Type1Fail);
var second = match2 ? GetValid(LG1TypeMatch2) : GetInvalid(LG1Type2Fail);
var first = match1 ? GetValid(G1TypeMatch1) : GetInvalid(G1Type1Fail);
var second = match2 ? GetValid(G1TypeMatch2) : GetInvalid(G1Type2Fail);
data.AddLine(first);
data.AddLine(second);
}
@ -454,7 +453,7 @@ private CheckResult GetWasTradeback(LegalityAnalysis data, PK1 pk1, TimeCapsuleE
{
var rate = pk1.CatchRate;
if (PK1.IsCatchRateHeldItem(rate))
return GetValid(LG1CatchRateMatchTradeback);
return GetValid(G1CatchRateMatchTradeback);
return GetWasNotTradeback(data, pk1, eval);
}
@ -462,20 +461,20 @@ private CheckResult GetWasNotTradeback(LegalityAnalysis data, PK1 pk1, TimeCapsu
{
var rate = pk1.CatchRate;
if (MoveInfo.IsAnyFromGeneration(2, data.Info.Moves))
return GetInvalid(LG1CatchRateItem);
return GetInvalid(G1CatchRateItem);
var e = data.EncounterMatch;
if (e is EncounterGift1 { Version: GameVersion.Stadium } or EncounterTrade1)
return GetValid(LG1CatchRateMatchPrevious); // Encounters detected by the catch rate, cant be invalid if match this encounters
return GetValid(G1CatchRateMatchPrevious); // Encounters detected by the catch rate, cant be invalid if match this encounters
ushort species = pk1.Species;
if (GBRestrictions.IsSpeciesNotAvailableCatchRate((byte)species) && rate == PersonalTable.RB[species].CatchRate)
{
if (species != (int)Species.Dragonite || rate != 45 || !(e.Version == GameVersion.BU || e.Version.Contains(GameVersion.YW)))
return GetInvalid(LG1CatchRateEvo);
return GetInvalid(G1CatchRateEvo);
}
if (!GBRestrictions.RateMatchesEncounter(e.Species, e.Version, rate))
return GetInvalid(eval == TimeCapsuleEvaluation.Transferred12 ? LG1CatchRateChain : LG1CatchRateNone);
return GetValid(LG1CatchRateMatchPrevious);
return GetInvalid(eval == TimeCapsuleEvaluation.Transferred12 ? G1CatchRateChain : G1CatchRateNone);
return GetValid(G1CatchRateMatchPrevious);
}
private static void VerifyMiscFatefulEncounter(LegalityAnalysis data)
@ -509,7 +508,7 @@ private static void VerifyMiscFatefulEncounter(LegalityAnalysis data)
return;
}
if (pk.FatefulEncounter)
data.AddLine(GetInvalid(LFatefulInvalid, Fateful));
data.AddLine(GetInvalid(Fateful, FatefulInvalid));
}
private static void VerifyMiscEggCommon(LegalityAnalysis data)
@ -518,30 +517,17 @@ private static void VerifyMiscEggCommon(LegalityAnalysis data)
var enc = data.EncounterMatch;
if (!EggStateLegality.GetIsEggHatchCyclesValid(pk, enc))
data.AddLine(GetInvalid(LEggHatchCycles, Egg));
data.AddLine(GetInvalid(Egg, EggHatchCycles));
if (pk.Format >= 6 && enc is IEncounterEgg && !MovesMatchRelearn(pk))
{
const int moveCount = 4;
var sb = new StringBuilder(64);
for (int i = 0; i < moveCount; i++)
{
var move = pk.GetRelearnMove(i);
var name = ParseSettings.GetMoveName(move);
sb.Append(name);
if (i != moveCount - 1)
sb.Append(", ");
}
var msg = string.Format(LMoveFExpect_0, sb);
data.AddLine(GetInvalid(msg, Egg));
}
data.AddLine(GetInvalid(Egg, MovesShouldMatchRelearnMoves));
if (pk is ITechRecord record)
{
if (record.GetMoveRecordFlagAny())
data.AddLine(GetInvalid(LEggRelearnFlags, Egg));
data.AddLine(GetInvalid(Egg, EggRelearnFlags));
if (pk.StatNature != pk.Nature)
data.AddLine(GetInvalid(LEggNature, Egg));
data.AddLine(GetInvalid(Egg, EggNature));
}
}
@ -569,14 +555,14 @@ private static void VerifyFatefulMysteryGift(LegalityAnalysis data, MysteryGift
{
var locToCheck = pk.IsEgg ? pk.MetLocation : pk.EggLocation;
if (locToCheck is not (Locations.LinkTrade5 or Locations.LinkTrade5NPC))
data.AddLine(GetInvalid(LPIDTypeMismatch, PID));
data.AddLine(GetInvalid(PID, PIDTypeMismatch));
}
}
bool shouldHave = g.FatefulEncounter;
var result = pk.FatefulEncounter == shouldHave
? GetValid(LFatefulMystery, Fateful)
: GetInvalid(LFatefulMysteryMissing, Fateful);
? GetValid(Fateful, FatefulMystery)
: GetInvalid(Fateful, FatefulMysteryMissing);
data.AddLine(result);
}
@ -585,21 +571,22 @@ private static void VerifyReceivability(LegalityAnalysis data, MysteryGift g)
var pk = data.Entity;
switch (g)
{
case PCD pcd when !pcd.CanBeReceivedByVersion(pk.Version) && pcd.Gift.PK.Version == 0:
case WC6 wc6 when !wc6.CanBeReceivedByVersion(pk.Version) && !pk.WasTradedEgg:
case WC7 wc7 when !wc7.CanBeReceivedByVersion(pk.Version) && !pk.WasTradedEgg:
case WC8 wc8 when !wc8.CanBeReceivedByVersion(pk.Version):
case WB8 wb8 when !wb8.CanBeReceivedByVersion(pk.Version, pk):
case WA8 wa8 when !wa8.CanBeReceivedByVersion(pk.Version, pk):
data.AddLine(GetInvalid(LEncGiftVersionNotDistributed, GameOrigin));
data.AddLine(GetInvalid(GameOrigin, EncGiftVersionNotDistributed));
return;
case PGF pgf when pgf.RestrictLanguage != 0 && pk.Language != pgf.RestrictLanguage:
data.AddLine(GetInvalid(string.Format(LOTLanguage, pgf.RestrictLanguage, pk.Language), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, EncGiftLanguageNotDistributed_0, (ushort)pgf.RestrictLanguage));
return;
case WC6 wc6 when wc6.RestrictLanguage != 0 && pk.Language != wc6.RestrictLanguage:
data.AddLine(GetInvalid(string.Format(LOTLanguage, wc6.RestrictLanguage, pk.Language), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, EncGiftLanguageNotDistributed_0, (ushort)wc6.RestrictLanguage));
return;
case WC7 wc7 when wc7.RestrictLanguage != 0 && pk.Language != wc7.RestrictLanguage:
data.AddLine(GetInvalid(string.Format(LOTLanguage, wc7.RestrictLanguage, pk.Language), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, EncGiftLanguageNotDistributed_0, (ushort)wc7.RestrictLanguage));
return;
}
}
@ -608,15 +595,15 @@ private static void VerifyGift3Shiny(LegalityAnalysis data, EncounterGift3 g3)
{
// check for shiny locked gifts
if (!g3.Shiny.IsValid(data.Entity))
data.AddLine(GetInvalid(LEncGiftShinyMismatch, Fateful));
data.AddLine(GetInvalid(Fateful, EncGiftShinyMismatch));
}
private static void VerifyFatefulIngameActive(LegalityAnalysis data)
{
var pk = data.Entity;
var result = pk.FatefulEncounter
? GetValid(LFateful, Fateful)
: GetInvalid(LFatefulMissing, Fateful);
? GetValid(Fateful, Valid)
: GetInvalid(Fateful, FatefulMissing);
data.AddLine(result);
}
@ -635,7 +622,7 @@ public void VerifyVersionEvolution(LegalityAnalysis data)
bool Sun() => ((uint)pk.Version & 1) == 0;
bool Moon() => ((uint)pk.Version & 1) == 1;
if (pk.IsUntraded)
data.AddLine(GetInvalid(LEvoTradeRequired, Evolution));
data.AddLine(GetInvalid(Evolution, EvoTradeRequired));
break;
}
}
@ -645,21 +632,21 @@ private static void VerifyFullness(LegalityAnalysis data, PKM pk, IFullnessEnjoy
if (pk.IsEgg)
{
if (fe.Fullness != 0)
data.AddLine(GetInvalid(string.Format(LMemoryStatFullness, "0"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatFullness_0, 0));
if (fe.Enjoyment != 0)
data.AddLine(GetInvalid(string.Format(LMemoryStatEnjoyment, "0"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatEnjoyment_0, 0));
return;
}
if (pk.Format >= 8)
{
if (fe.Fullness > 245) // Exiting camp is -10, so a 255=>245 is max.
data.AddLine(GetInvalid(string.Format(LMemoryStatFullness, "<=245"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatFullnessLEQ_0, 245));
else if (fe.Fullness is not 0 && pk is not PK8) // BD/SP and PLA do not set this field, even via HOME.
data.AddLine(GetInvalid(string.Format(LMemoryStatFullness, "0"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatFullness_0, 0));
if (fe.Enjoyment != 0)
data.AddLine(GetInvalid(string.Format(LMemoryStatEnjoyment, "0"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatEnjoyment_0, 0));
return;
}
@ -673,7 +660,7 @@ private static void VerifyFullness(LegalityAnalysis data, PKM pk, IFullnessEnjoy
return; // evolved
if (IsUnfeedable(pk.Species))
data.AddLine(GetInvalid(string.Format(LMemoryStatFullness, "0"), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatFullness_0, 0));
}
public static bool IsUnfeedable(ushort species) => species is
@ -688,16 +675,17 @@ private static void VerifyFullness(LegalityAnalysis data, PKM pk, IFullnessEnjoy
private static void VerifyStats7b(LegalityAnalysis data, PB7 pb7)
{
VerifyAbsoluteSizes(data, pb7);
var calc = pb7.CalcCP;
if (pb7.Stat_CP != pb7.CalcCP && !IsStarterLGPE(pb7))
data.AddLine(GetInvalid(LStatIncorrectCP, Encounter));
data.AddLine(GetInvalid(Encounter, StatIncorrectCP_0, (uint)calc));
if (pb7.ReceivedTime is null)
data.AddLine(GetInvalid(LDateTimeClockInvalid, Misc));
data.AddLine(GetInvalid(Misc, DateTimeClockInvalid));
// HOME moving in and out will retain received date. ensure it matches if no HT data present.
// Go Park captures will have different dates, as the GO met date is retained as Met Date.
if (pb7.ReceivedDate is not { } date || !EncounterDate.IsValidDateSwitch(date) || (pb7.IsUntraded && data.EncounterOriginal is not EncounterSlot7GO && date != pb7.MetDate))
data.AddLine(GetInvalid(LDateOutsideConsoleWindow, Misc));
data.AddLine(GetInvalid(Misc, DateOutsideConsoleWindow));
}
private static void VerifyAbsoluteSizes<T>(LegalityAnalysis data, T obj) where T : IScaledSizeValue
@ -715,10 +703,13 @@ private static void VerifyStats7b(LegalityAnalysis data, PB7 pb7)
{
// Unlike PLA, there is no way to force it to recalculate in-game.
// The only encounter this applies to is Meltan, which cannot reach PLA for recalculation.
if (obj.HeightAbsolute != enc.GetHomeHeightAbsolute())
data.AddLine(GetInvalid(LStatIncorrectHeight, Encounter));
if (obj.WeightAbsolute != enc.GetHomeWeightAbsolute())
data.AddLine(GetInvalid(LStatIncorrectWeight, Encounter));
var expectHeight = enc.GetHomeHeightAbsolute();
if (obj.HeightAbsolute != expectHeight)
data.AddLine(GetInvalid(Encounter, StatIncorrectHeight, BitConverter.SingleToUInt32Bits(expectHeight)));
var expectWeight = enc.GetHomeWeightAbsolute();
if (obj.WeightAbsolute != expectWeight)
data.AddLine(GetInvalid(Encounter, StatIncorrectWeight, BitConverter.SingleToUInt32Bits(expectWeight)));
}
private static void VerifyFixedSizeMidAlpha(LegalityAnalysis data, PA8 pk)
@ -742,10 +733,13 @@ private static void VerifyFixedSizeMidAlpha(LegalityAnalysis data, PA8 pk)
private static void VerifyCalculatedSizes<T>(LegalityAnalysis data, T obj) where T : IScaledSizeValue
{
if (obj.HeightAbsolute != obj.CalcHeightAbsolute)
data.AddLine(GetInvalid(LStatIncorrectHeight, Encounter));
var expectHeight = obj.CalcHeightAbsolute;
if (obj.HeightAbsolute != expectHeight)
data.AddLine(GetInvalid(Encounter, StatIncorrectHeight, BitConverter.SingleToUInt32Bits(expectHeight)));
var expectWeight = obj.CalcWeightAbsolute;
if (obj.WeightAbsolute != obj.CalcWeightAbsolute)
data.AddLine(GetInvalid(LStatIncorrectWeight, Encounter));
data.AddLine(GetInvalid(Encounter, StatIncorrectWeight, BitConverter.SingleToUInt32Bits(expectWeight)));
}
// ReSharper restore CompareOfFloatsByEqualityOperator
@ -762,31 +756,31 @@ private void VerifyStats8(LegalityAnalysis data, PK8 pk8)
if (pk8.IsEgg)
{
if (social != 0)
data.AddLine(GetInvalid(LMemorySocialZero, Encounter));
data.AddLine(GetInvalid(Encounter, MemorySocialZero));
}
else if (social > byte.MaxValue)
{
data.AddLine(GetInvalid(string.Format(LMemorySocialTooHigh_0, byte.MaxValue), Encounter));
data.AddLine(GetInvalid(Encounter, MemoryStatSocialLEQ_0, 0));
}
VerifyStatNature(data, pk8);
if (!pk8.IsBattleVersionValid(data.Info.EvoChainsAllGens))
data.AddLine(GetInvalid(LStatBattleVersionInvalid));
data.AddLine(GetInvalid(StatBattleVersionInvalid));
var enc = data.EncounterMatch;
bool originGMax = enc is IGigantamaxReadOnly {CanGigantamax: true};
if (originGMax != pk8.CanGigantamax)
{
bool ok = !pk8.IsEgg && Gigantamax.CanToggle(pk8.Species, pk8.Form, enc.Species, enc.Form);
var chk = ok ? GetValid(LStatGigantamaxValid) : GetInvalid(LStatGigantamaxInvalid);
var chk = ok ? GetValid(StatGigantamaxValid) : GetInvalid(StatGigantamaxInvalid);
data.AddLine(chk);
}
if (pk8.DynamaxLevel != 0)
{
if (!pk8.CanHaveDynamaxLevel(pk8) || pk8.DynamaxLevel > 10)
data.AddLine(GetInvalid(LStatDynamaxInvalid));
data.AddLine(GetInvalid(StatDynamaxInvalid));
}
VerifyTechRecordSWSH(data, pk8);
@ -799,21 +793,21 @@ private void VerifyStats8a(LegalityAnalysis data, PA8 pa8)
var social = pa8.Sociability;
if (social != 0)
data.AddLine(GetInvalid(LMemorySocialZero, Encounter));
data.AddLine(GetInvalid(Encounter, MemorySocialZero));
VerifyStatNature(data, pa8);
if (!pa8.IsBattleVersionValid(data.Info.EvoChainsAllGens))
data.AddLine(GetInvalid(LStatBattleVersionInvalid));
data.AddLine(GetInvalid(StatBattleVersionInvalid));
if (pa8.CanGigantamax)
data.AddLine(GetInvalid(LStatGigantamaxInvalid));
data.AddLine(GetInvalid(StatGigantamaxInvalid));
if (pa8.DynamaxLevel != 0)
data.AddLine(GetInvalid(LStatDynamaxInvalid));
data.AddLine(GetInvalid(StatDynamaxInvalid));
if (pa8.GetMoveRecordFlagAny() && !pa8.IsEgg) // already checked for eggs
data.AddLine(GetInvalid(LEggRelearnFlags));
data.AddLine(GetInvalid(EggRelearnFlags));
VerifyTechRecordSWSH(data, pa8);
}
@ -822,28 +816,28 @@ private void VerifyStats8b(LegalityAnalysis data, PB8 pb8)
{
var social = pb8.Sociability;
if (social != 0)
data.AddLine(GetInvalid(LMemorySocialZero, Encounter));
data.AddLine(GetInvalid(Encounter, MemorySocialZero));
if (pb8.IsDprIllegal)
data.AddLine(GetInvalid(LTransferFlagIllegal));
data.AddLine(GetInvalid(TransferFlagIllegal));
if (pb8.Species is (int)Species.Spinda or (int)Species.Nincada && !pb8.BDSP)
data.AddLine(GetInvalid(LTransferNotPossible));
data.AddLine(GetInvalid(TransferNotPossible));
if (pb8.Species is (int)Species.Spinda && pb8.Tracker != 0)
data.AddLine(GetInvalid(LTransferTrackerShouldBeZero));
data.AddLine(GetInvalid(TransferTrackerShouldBeZero));
VerifyStatNature(data, pb8);
if (!pb8.IsBattleVersionValid(data.Info.EvoChainsAllGens))
data.AddLine(GetInvalid(LStatBattleVersionInvalid));
data.AddLine(GetInvalid(StatBattleVersionInvalid));
if (pb8.CanGigantamax)
data.AddLine(GetInvalid(LStatGigantamaxInvalid));
data.AddLine(GetInvalid(StatGigantamaxInvalid));
if (pb8.DynamaxLevel != 0)
data.AddLine(GetInvalid(LStatDynamaxInvalid));
data.AddLine(GetInvalid(StatDynamaxInvalid));
if (pb8.GetMoveRecordFlagAny() && !pb8.IsEgg) // already checked for eggs
data.AddLine(GetInvalid(LEggRelearnFlags));
data.AddLine(GetInvalid(EggRelearnFlags));
VerifyTechRecordSWSH(data, pb8);
}
@ -867,10 +861,10 @@ private static bool CheckHeightWeightOdds(IEncounterTemplate enc)
if (statNature == pk.Nature)
return;
if (!statNature.IsMint())
data.AddLine(GetInvalid(LStatNatureInvalid));
data.AddLine(GetInvalid(StatNatureInvalid));
}
private static string GetMoveName<T>(T pk, int index) where T : PKM, ITechRecord => ParseSettings.MoveStrings[pk.Permit.RecordPermitIndexes[index]];
private static ushort GetMoveIndex<T>(T pk, int index) where T : PKM, ITechRecord => pk.Permit.RecordPermitIndexes[index];
private void VerifyTechRecordSWSH<T>(LegalityAnalysis data, T pk) where T : PKM, ITechRecord
{
@ -882,7 +876,7 @@ private static bool CheckHeightWeightOdds(IEncounterTemplate enc)
{
if (!pk.GetMoveRecordFlag(i))
continue;
data.AddLine(GetInvalid(string.Format(LMoveSourceTR, GetMoveName(pk, i))));
data.AddLine(GetInvalid(MoveTechRecordFlagMissing_0, GetMoveIndex(pk, i)));
}
}
else
@ -908,7 +902,7 @@ private static bool CheckHeightWeightOdds(IEncounterTemplate enc)
continue;
}
data.AddLine(GetInvalid(string.Format(LMoveSourceTR, GetMoveName(pk, i))));
data.AddLine(GetInvalid(MoveTechRecordFlagMissing_0, GetMoveIndex(pk, i)));
}
}
}
@ -929,7 +923,7 @@ private void VerifyTechRecordSV(LegalityAnalysis data, PK9 pk)
{
if (!pk.GetMoveRecordFlag(i))
continue;
data.AddLine(GetInvalid(string.Format(LMoveSourceTR, GetMoveName(pk, i))));
data.AddLine(GetInvalid(MoveTechRecordFlagMissing_0, GetMoveIndex(pk, i)));
}
}
else
@ -978,7 +972,7 @@ private void VerifyTechRecordSV(LegalityAnalysis data, PK9 pk)
if (preEvoHas)
continue;
}
data.AddLine(GetInvalid(string.Format(LMoveSourceTR, GetMoveName(pk, i))));
data.AddLine(GetInvalid(MoveTechRecordFlagMissing_0, GetMoveIndex(pk, i)));
}
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -22,9 +22,9 @@ private void VerifyEgg(LegalityAnalysis data)
{
var pk = data.Entity;
if (pk.Move1_PPUps != 0 || pk.Move2_PPUps != 0 || pk.Move3_PPUps != 0 || pk.Move4_PPUps != 0)
data.AddLine(GetInvalid(LEggPPUp, CheckIdentifier.Egg));
data.AddLine(GetInvalid(CheckIdentifier.Egg, EggPPUp));
if (!IsZeroMovePP(pk))
data.AddLine(GetInvalid(LEggPP, CheckIdentifier.Egg));
data.AddLine(GetInvalid(CheckIdentifier.Egg, EggPP));
}
private static bool IsZeroMovePP(PKM pk)
@ -58,7 +58,7 @@ private void VerifyEntity(LegalityAnalysis data)
for (int i = 0; i < ups.Length; i++)
{
if (ups[i] != 0)
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, i + 1)));
data.AddLine(GetInvalid(MovePPUpsTooHigh_0, (ushort)(i + 1)));
}
}
else // Check specific move indexes
@ -66,7 +66,7 @@ private void VerifyEntity(LegalityAnalysis data)
for (int i = 0; i < ups.Length; i++)
{
if (!Legal.IsPPUpAvailable(moves[i]) && ups[i] != 0)
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, i + 1)));
data.AddLine(GetInvalid(MovePPUpsTooHigh_0, (ushort)(i + 1)));
}
}
@ -74,9 +74,9 @@ private void VerifyEntity(LegalityAnalysis data)
{
var expect = pk.GetMovePP(moves[i], ups[i]);
if (pp[i] > expect)
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, i + 1)));
data.AddLine(GetInvalid(MovePPTooHigh_0, (ushort)(i + 1)));
else if (expectHeal && pp[i] != expect)
data.AddLine(GetInvalid(string.Format(LMovePPExpectHealed_0, i + 1)));
data.AddLine(GetInvalid(MovePPExpectHealed_0, (ushort)(i + 1)));
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.LanguageID;
namespace PKHeX.Core;
@ -20,13 +20,13 @@ public override void Verify(LegalityAnalysis data)
int len = pk.LoadString(pk.NicknameTrash, nickname);
if (len == 0)
{
data.AddLine(GetInvalid(LNickLengthShort));
data.AddLine(GetInvalid(NickLengthShort));
return;
}
nickname = nickname[..len];
if (nickname.Contains('\uffff') && pk is { Format: 4 })
{
data.AddLine(GetInvalid(LNickInvalidChar));
data.AddLine(GetInvalid(NickInvalidChar, ushort.MaxValue));
return;
}
@ -45,7 +45,7 @@ public override void Verify(LegalityAnalysis data)
if (pk.VC)
VerifyG1NicknameWithinBounds(data, nickname);
else if (IsMysteryGiftNoNickname(enc))
data.AddLine(Get(LEncGiftNicknamed, ParseSettings.Settings.Nickname.NicknamedMysteryGift(enc.Context)));
data.AddLine(Get(ParseSettings.Settings.Nickname.NicknamedMysteryGift(enc.Context), EncGiftNicknamed));
}
if (enc is IFixedTrainer t)
@ -68,10 +68,10 @@ public override void Verify(LegalityAnalysis data)
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format) && pk.IsNicknamed)
{
var mostRecentNicknameContext = pk.Format >= 8 ? pk.Context : enc.Context;
if (WordFilter.IsFiltered(nickname, out var badPattern, pk.Context, mostRecentNicknameContext))
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
if (WordFilter.IsFiltered(nickname, pk.Context, mostRecentNicknameContext, out var type, out var badPattern))
data.AddLine(GetInvalid(CheckIdentifier.Nickname, WordFilterFlaggedPattern_01, (ushort)type, (ushort)badPattern));
if (TrainerNameVerifier.ContainsTooManyNumbers(nickname, enc.Generation))
data.AddLine(GetInvalid("Word Filter: Too many numbers."));
data.AddLine(GetInvalid(CheckIdentifier.Nickname, WordFilterTooManyNumbers_0, (ushort)TrainerNameVerifier.GetMaxNumberCount(enc.Generation)));
}
}
@ -106,7 +106,7 @@ private void VerifyFixedNicknameEncounter(LegalityAnalysis data, ILangNicknamedT
return;
if (pk.IsNicknamed)
data.AddLine(Get(LEncGiftNicknamed, Severity.Invalid));
data.AddLine(Get(Severity.Invalid, EncGiftNicknamed));
return;
}
@ -122,14 +122,14 @@ private void VerifyFixedNicknameEncounter(LegalityAnalysis data, ILangNicknamedT
}
// Should have a nickname present.
data.AddLine(GetInvalid(LNickMatchLanguageFail));
data.AddLine(GetInvalid(NickMatchLanguageFail));
return;
}
// Encounter has a nickname, and PKM should have it.
bool matches = nickname.SequenceEqual(encounterNickname);
var severity = !matches || !pk.IsNicknamed ? Severity.Invalid : Severity.Valid;
data.AddLine(Get(LEncGiftNicknamed, severity));
data.AddLine(Get(severity, EncGiftNicknamed));
}
private void VerifyHomeGiftNickname(LegalityAnalysis data, IEncounterTemplate enc, ILangNick pk, ReadOnlySpan<char> nickname)
@ -141,14 +141,14 @@ private void VerifyHomeGiftNickname(LegalityAnalysis data, IEncounterTemplate en
// Can't nickname everything.
if (enc.Species == (int) Species.Melmetal)
{
data.AddLine(GetInvalid(LEncGiftNicknamed));
data.AddLine(GetInvalid(EncGiftNicknamed));
return;
}
// Ensure the nickname does not match species name
var orig = SpeciesName.GetSpeciesNameGeneration(enc.Species, pk.Language, enc.Generation);
if (nickname.SequenceEqual(orig))
data.AddLine(GetInvalid(LNickMatchLanguageFlag));
data.AddLine(GetInvalid(NickMatchLanguageFlag));
}
private bool VerifyUnNicknamedEncounter(LegalityAnalysis data, PKM pk, ReadOnlySpan<char> nickname, IEncounterTemplate enc)
@ -161,29 +161,29 @@ private bool VerifyUnNicknamedEncounter(LegalityAnalysis data, PKM pk, ReadOnlyS
// Setting the nickname to the same as the species name does not set the Nickname flag (equals unmodified, no flag)
if (!SpeciesName.IsNicknamed(pk.Species, nickname, pk.Language, pk.Format))
{
data.AddLine(Get(LNickMatchLanguageFlag, Severity.Invalid));
data.AddLine(Get(Severity.Invalid, NickMatchLanguageFlag));
return true;
}
}
if (SpeciesName.TryGetSpeciesAnyLanguage(nickname, out var species, pk.Format))
{
var msg = species == pk.Species ? LNickMatchLanguageFlag : LNickMatchNoOthersFail;
data.AddLine(Get(msg, ParseSettings.Settings.Nickname.NicknamedAnotherSpecies));
var msg = species == pk.Species ? NickMatchLanguageFlag : NickMatchNoOthersFail;
data.AddLine(Get(ParseSettings.Settings.Nickname.NicknamedAnotherSpecies, msg));
return true;
}
if (pk.Format <= 7 && StringConverter.HasEastAsianScriptCharacters(nickname) && pk is not PB7) // East Asian Scripts
{
data.AddLine(GetInvalid(LNickInvalidChar));
data.AddLine(GetInvalid(NickInvalidChar));
return true;
}
if (nickname.Length > Legal.GetMaxLengthNickname(enc.Generation, (LanguageID)pk.Language))
{
int length = GetForeignNicknameLength(pk, enc, enc.Generation);
var severe = (length != 0 && nickname.Length <= length) ? Severity.Fishy : Severity.Invalid;
data.AddLine(Get(LNickLengthLong, severe));
data.AddLine(Get(severe, NickLengthLong));
return true;
}
data.AddLine(GetValid(LNickMatchNoOthers));
data.AddLine(GetValid(NickMatchNoOthers));
}
else
{
@ -198,13 +198,13 @@ private void VerifyUnNicknamed(LegalityAnalysis data, PKM pk, ReadOnlySpan<char>
if (pk.Format < 3)
{
// pk1/pk2 IsNicknamed getter checks for match, logic should only reach here if matches.
data.AddLine(GetValid(LNickMatchLanguage));
data.AddLine(GetValid(NickMatchLanguage));
}
else
{
var enc = data.EncounterOriginal;
bool valid = IsNicknameValid(pk, enc, nickname);
var result = valid ? GetValid(LNickMatchLanguage) : GetInvalid(LNickMatchLanguageFail);
var result = valid ? GetValid(NickMatchLanguage) : GetInvalid(NickMatchLanguageFail);
data.AddLine(result);
}
}
@ -318,18 +318,18 @@ private static void VerifyNicknameEgg(LegalityAnalysis data)
bool flagState = EggStateLegality.IsNicknameFlagSet(enc, pk);
if (pk.IsNicknamed != flagState)
data.AddLine(GetInvalid(flagState ? LNickFlagEggYes : LNickFlagEggNo, CheckIdentifier.Egg));
data.AddLine(GetInvalid(CheckIdentifier.Egg, flagState ? NickFlagEggYes : NickFlagEggNo));
Span<char> nickname = stackalloc char[pk.TrashCharCountNickname];
int len = pk.LoadString(pk.NicknameTrash, nickname);
nickname = nickname[..len];
if (pk.Format == 2 && !SpeciesName.IsNicknamedAnyLanguage(0, nickname, 2))
data.AddLine(GetValid(LNickMatchLanguageEgg, CheckIdentifier.Egg));
data.AddLine(GetValid(CheckIdentifier.Egg, NickMatchLanguageEgg));
else if (!nickname.SequenceEqual(SpeciesName.GetEggName(pk.Language, enc.Generation)))
data.AddLine(GetInvalid(LNickMatchLanguageEggFail, CheckIdentifier.Egg));
data.AddLine(GetInvalid(CheckIdentifier.Egg, NickMatchLanguageEggFail));
else
data.AddLine(GetValid(LNickMatchLanguageEgg, CheckIdentifier.Egg));
data.AddLine(GetValid(CheckIdentifier.Egg, NickMatchLanguageEgg));
}
private static void VerifyNicknameTrade(LegalityAnalysis data, IEncounterTemplate t)
@ -351,21 +351,21 @@ private void VerifyG1NicknameWithinBounds(LegalityAnalysis data, ReadOnlySpan<ch
if (StringConverter1.GetIsEnglish(str))
{
if (str.Length > 10)
data.AddLine(GetInvalid(LNickLengthLong));
data.AddLine(GetInvalid(NickLengthLong, 10));
}
else if (StringConverter1.GetIsJapanese(str))
{
if (str.Length > 5)
data.AddLine(GetInvalid(LNickLengthLong));
data.AddLine(GetInvalid(NickLengthLong, 5));
}
else if (pk.Korean && StringConverter2KOR.GetIsKorean(str))
{
if (str.Length > 5)
data.AddLine(GetInvalid(LNickLengthLong));
data.AddLine(GetInvalid(NickLengthLong, 5));
}
else
{
data.AddLine(GetInvalid(LG1CharNick));
data.AddLine(GetInvalid(G1CharNick));
}
}
@ -373,7 +373,7 @@ private static void VerifyTrade4(LegalityAnalysis data, EncounterTrade4PID t)
{
var pk = data.Entity;
if (t.IsIncorrectEnglish(pk))
data.AddLine(GetInvalid(string.Format(LOTLanguage, Japanese, English), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, OTLanguageShouldBeLeq_0, (byte)Japanese));
var lang = t.DetectOriginalLanguage(pk);
VerifyTrade(data, t, lang);
}
@ -401,7 +401,7 @@ private static void VerifyTrade8b(LegalityAnalysis data, EncounterTrade8b t)
lang = t.DetectMeisterMagikarpLanguage(nickname, trainer, lang);
if (lang == -1) // err
data.AddLine(GetInvalid(string.Format(LOTLanguage, $"{Japanese}/{German}", $"{(LanguageID)pk.Language}"), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, OTLanguageShouldBe_0or1, (byte)Japanese, (byte)German));
}
if (t.IsPijako(pk))
@ -418,7 +418,7 @@ private static void VerifyEncounterTrade5(LegalityAnalysis data, EncounterTrade5
var pk = data.Entity;
var lang = pk.Language;
if (pk.Format == 5 && lang == (int)Japanese)
data.AddLine(GetInvalid(string.Format(LOTLanguage, 0, Japanese), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, OTLanguageShouldBe_0, (byte)0));
lang = Math.Max(lang, 1);
VerifyTrade(data, t, lang);
@ -434,7 +434,7 @@ private static CheckResult CheckTradeOTOnly(LegalityAnalysis data, IFixedTrainer
{
var pk = data.Entity;
if (pk.IsNicknamed && (pk.Format < 8 || pk.FatefulEncounter))
return GetInvalid(LEncTradeChangedNickname, CheckIdentifier.Nickname);
return GetInvalid(CheckIdentifier.Nickname, EncTradeChangedNickname);
int lang = pk.Language;
Span<char> trainer = stackalloc char[pk.TrashCharCountTrainer];
@ -442,8 +442,8 @@ private static CheckResult CheckTradeOTOnly(LegalityAnalysis data, IFixedTrainer
trainer = trainer[..len];
if (!t.IsTrainerMatch(pk, trainer, lang))
return GetInvalid(LEncTradeIndexBad, CheckIdentifier.Trainer);
return GetValid(LEncTradeUnchanged, CheckIdentifier.Nickname);
return GetInvalid(CheckIdentifier.Trainer, EncTradeIndexBad);
return GetValid(CheckIdentifier.Nickname, EncTradeUnchanged);
}
private static void VerifyTrade(LegalityAnalysis data, IEncounterTemplate t, int language)
@ -458,8 +458,8 @@ private static void VerifyNickname(LegalityAnalysis data, IFixedNickname fn, int
{
var pk = data.Entity;
var result = fn.IsNicknameMatch(pk, pk.Nickname, language)
? GetValid(LEncTradeUnchanged, CheckIdentifier.Nickname)
: Get(LEncTradeChangedNickname, ParseSettings.Settings.Nickname.NicknamedTrade(data.EncounterOriginal.Context), CheckIdentifier.Nickname);
? GetValid(CheckIdentifier.Nickname, EncTradeUnchanged)
: Get(CheckIdentifier.Nickname, ParseSettings.Settings.Nickname.NicknamedTrade(data.EncounterOriginal.Context), EncTradeChangedNickname);
data.AddLine(result);
}
@ -471,6 +471,6 @@ private static void VerifyTrainerName(LegalityAnalysis data, IFixedTrainer ft, i
trainer = trainer[..len];
if (!ft.IsTrainerMatch(pk, trainer, language))
data.AddLine(GetInvalid(LEncTradeChangedOT, CheckIdentifier.Trainer));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, EncTradeChangedOT));
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -23,9 +23,9 @@ public override void Verify(LegalityAnalysis data)
VerifyEC100(data, enc.Species);
if (pk.PID == 0)
data.AddLine(Get(LPIDZero, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, PIDZero));
if (!pk.Nature.IsFixed()) // out of range
data.AddLine(GetInvalid(LPIDNatureMismatch));
data.AddLine(GetInvalid(PIDNatureMismatch));
if (data.Info.EncounterMatch is IEncounterEgg egg)
VerifyEggPID(data, pk, egg);
@ -39,7 +39,7 @@ private static void VerifyEggPID(LegalityAnalysis data, PKM pk, IEncounterEgg eg
// Gen5 eggs use rand(0xFFFFFFFF), which never yields 0xFFFFFFFF (max 0xFFFFFFFE).
// Masuda Method does the same as the original PID roll. PID is never re-rolled a different way.
if (pk.EncryptionConstant == uint.MaxValue)
data.AddLine(Get(LPIDEncryptZero, Severity.Invalid, CheckIdentifier.EC));
data.AddLine(Get(CheckIdentifier.EC, Severity.Invalid, PIDEncryptZero));
}
else if (egg is EncounterEgg4)
{
@ -50,7 +50,7 @@ private static void VerifyEggPID(LegalityAnalysis data, PKM pk, IEncounterEgg eg
// None of the un-rolled states share the same shiny-xor as PID=0, you can re-roll into an all-zero PID.
// Flag it as fishy, because more often than not, it is hacked rather than a legitimately obtained egg.
if (pk.EncryptionConstant == 0)
data.AddLine(Get(LPIDEncryptZero, Severity.Fishy, CheckIdentifier.EC));
data.AddLine(Get(CheckIdentifier.EC, Severity.Fishy, PIDEncryptZero));
if (Breeding.IsGenderSpeciesDetermination(egg.Species))
VerifyEggGender8000(data, pk);
@ -58,7 +58,7 @@ private static void VerifyEggPID(LegalityAnalysis data, PKM pk, IEncounterEgg eg
else if (egg is EncounterEgg3)
{
if (!Daycare3.IsValidProcPID(pk.EncryptionConstant, egg.Version))
data.AddLine(Get(LPIDEncryptZero, Severity.Invalid, CheckIdentifier.EC));
data.AddLine(Get(CheckIdentifier.EC, Severity.Invalid, PIDEncryptZero));
if (Breeding.IsGenderSpeciesDetermination(egg.Species))
VerifyEggGender8000(data, pk);
@ -72,7 +72,7 @@ private static void VerifyEggGender8000(LegalityAnalysis data, PKM pk)
if (Breeding.IsValidSpeciesBit34(pk.EncryptionConstant, gender))
return; // 50/50 chance!
if (gender == 1 || IsEggBitRequiredMale34(data.Info.Moves))
data.AddLine(GetInvalid(LPIDGenderMismatch, CheckIdentifier.EC));
data.AddLine(GetInvalid(CheckIdentifier.EC, PIDGenderMismatch));
}
private void VerifyShiny(LegalityAnalysis data)
@ -81,7 +81,7 @@ private void VerifyShiny(LegalityAnalysis data)
var enc = data.EncounterMatch;
if (!enc.Shiny.IsValid(pk))
data.AddLine(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.Shiny));
data.AddLine(GetInvalid(CheckIdentifier.Shiny, EncStaticPIDShiny));
switch (enc)
{
@ -91,7 +91,7 @@ private void VerifyShiny(LegalityAnalysis data)
VerifyG5PID_IDCorrelation(data);
break;
case EncounterSlot5 {IsHiddenGrotto: true} when pk.IsShiny:
data.AddLine(GetInvalid(LG5PIDShinyGrotto, CheckIdentifier.Shiny));
data.AddLine(GetInvalid(CheckIdentifier.Shiny, G5PIDShinyGrotto));
break;
case EncounterSlot5 {IsHiddenGrotto: false}:
VerifyG5PID_IDCorrelation(data);
@ -99,16 +99,16 @@ private void VerifyShiny(LegalityAnalysis data)
case PCD d: // fixed PID
if (d.IsFixedPID() && pk.EncryptionConstant != d.Gift.PK.PID)
data.AddLine(GetInvalid(LEncGiftPIDMismatch, CheckIdentifier.Shiny));
data.AddLine(GetInvalid(CheckIdentifier.Shiny, EncGiftPIDMismatch));
break;
case WC7 { IsAshGreninja: true } when pk.IsShiny:
data.AddLine(GetInvalid(LEncGiftShinyMismatch, CheckIdentifier.Shiny));
data.AddLine(GetInvalid(CheckIdentifier.Shiny, EncGiftShinyMismatch));
break;
// Underground Raids are originally anti-shiny on encounter.
// When selecting a prize at the end, the game rolls and force-shiny is applied to be XOR=1.
case EncounterStatic8U u when !u.IsShinyXorValid(pk.ShinyXor):
data.AddLine(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.Shiny));
data.AddLine(GetInvalid(CheckIdentifier.Shiny, EncStaticPIDShiny));
break;
}
}
@ -118,7 +118,7 @@ private void VerifyG5PID_IDCorrelation(LegalityAnalysis data)
var pk = data.Entity;
var result = MonochromeRNG.GetBitXor(pk, pk.EncryptionConstant);
if (result != 0)
data.AddLine(GetInvalid(LPIDTypeMismatch));
data.AddLine(GetInvalid(PIDTypeMismatch));
}
private static void VerifyECPIDWurmple(LegalityAnalysis data)
@ -129,14 +129,12 @@ private static void VerifyECPIDWurmple(LegalityAnalysis data)
{
// Indicate what it will evolve into
var evoVal = WurmpleUtil.GetWurmpleEvoVal(pk.EncryptionConstant);
var evolvesTo = evoVal == WurmpleEvolution.Silcoon ? (int)Species.Beautifly : (int)Species.Dustox;
var species = ParseSettings.SpeciesStrings[evolvesTo];
var msg = string.Format(L_XWurmpleEvo_0, species);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
var evolvesTo = evoVal == WurmpleEvolution.Silcoon ? (ushort)Species.Beautifly : (ushort)Species.Dustox;
data.AddLine(GetValid(CheckIdentifier.EC, HintEvolvesToSpecies_0, evolvesTo));
}
else if (!WurmpleUtil.IsWurmpleEvoValid(pk))
{
data.AddLine(GetInvalid(LPIDEncryptWurmple, CheckIdentifier.EC));
data.AddLine(GetInvalid(CheckIdentifier.EC, PIDEncryptWurmple));
}
}
@ -147,14 +145,9 @@ private static void VerifyEC100(LegalityAnalysis data, ushort encSpecies)
return; // Evolved, don't need to calculate the final evolution for the verbose report.
// Indicate the evolution for the user.
const EntityContext mostRecent = Latest.Context; // latest ec100 form here
uint evoVal = pk.EncryptionConstant % 100;
bool rare = evoVal == 0;
var (species, form) = EvolutionRestrictions.GetEvolvedSpeciesFormEC100(encSpecies, rare);
var str = GameInfo.Strings;
var forms = FormConverter.GetFormList(species, str.Types, str.forms, GameInfo.GenderSymbolASCII, mostRecent);
var msg = string.Format(L_XRareFormEvo_0_1, forms[form], rare);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
var rare = EvolutionRestrictions.IsEvolvedSpeciesFormRare(pk.EncryptionConstant);
var hint = rare ? (byte)1 : (byte)0;
data.AddLine(GetValid(CheckIdentifier.EC, HintEvolvesToRareForm_0, hint));
}
private static void VerifyEC(LegalityAnalysis data)
@ -166,7 +159,7 @@ private static void VerifyEC(LegalityAnalysis data)
{
if (Info.EncounterMatch is WC8 {IsHOMEGift: true})
return; // HOME Gifts
data.AddLine(Get(LPIDEncryptZero, Severity.Fishy, CheckIdentifier.EC));
data.AddLine(Get(CheckIdentifier.EC, Severity.Fishy, PIDEncryptZero));
}
// Gen3-5 => Gen6 have PID==EC with an edge case exception.
@ -186,7 +179,7 @@ private static void VerifyEC(LegalityAnalysis data)
if (enc is WB8 {IsEquivalentFixedECPID: true})
return;
data.AddLine(GetInvalid(LPIDEqualsEC, CheckIdentifier.EC)); // better to flag than 1:2^32 odds since RNG is not feasible to yield match
data.AddLine(GetInvalid(CheckIdentifier.EC, PIDEqualsEC)); // better to flag than 1:2^32 odds since RNG is not feasible to yield match
return;
}
@ -195,7 +188,7 @@ private static void VerifyEC(LegalityAnalysis data)
{
var xor = pk.ShinyXor;
if (xor >> 3 == 1) // 8 <= x <= 15
data.AddLine(Get(LTransferPIDECXor, Severity.Fishy, CheckIdentifier.EC));
data.AddLine(Get(CheckIdentifier.EC, Severity.Fishy, TransferEncryptGen6Xor));
}
}
@ -238,8 +231,8 @@ private static void VerifyTransferEC(LegalityAnalysis data)
if (pk.PID == expect)
return;
var msg = bitFlipProc ? LTransferPIDECBitFlip : LTransferPIDECEquals;
data.AddLine(GetInvalid(msg, CheckIdentifier.EC));
var msg = bitFlipProc ? TransferEncryptGen6BitFlip : TransferEncryptGen6Equals;
data.AddLine(GetInvalid(CheckIdentifier.EC, msg));
}
private static bool IsEggBitRequiredMale34(ReadOnlySpan<MoveResult> moves)

View File

@ -7,15 +7,15 @@ namespace PKHeX.Core;
/// <summary>
/// String Translation Utility
/// </summary>
public static class RibbonStrings
public class RibbonStrings
{
private static readonly Dictionary<string, string> RibbonNames = [];
private readonly Dictionary<string, string> RibbonNames = [];
/// <summary>
/// Resets the Ribbon Dictionary to use the supplied set of Ribbon (Property) Names.
/// </summary>
/// <param name="lines">Array of strings that are tab separated with Property Name, \t, and Display Name.</param>
public static void ResetDictionary(ReadOnlySpan<string> lines)
public RibbonStrings(ReadOnlySpan<string> lines)
{
RibbonNames.EnsureCapacity(lines.Length);
@ -38,11 +38,11 @@ public static void ResetDictionary(ReadOnlySpan<string> lines)
/// <param name="propertyName">Ribbon property name</param>
/// <param name="result">Ribbon localized name</param>
/// <returns>True if exists</returns>
public static bool GetNameSafe(string propertyName, [NotNullWhen(true)] out string? result) => RibbonNames.TryGetValue(propertyName, out result);
public bool GetNameSafe(string propertyName, [NotNullWhen(true)] out string? result) => RibbonNames.TryGetValue(propertyName, out result);
/// <returns>Ribbon display name</returns>
/// <inheritdoc cref="GetNameSafe"/>
public static string GetName(string propertyName)
public string GetName(string propertyName)
{
// Throw an exception with the requested property name as the message, rather than an ambiguous "key not present" message.
// We should ALWAYS have the key present as the input arguments are not user-defined, rather, they are from PKM property names.

View File

@ -1,6 +1,6 @@
using System;
using System.Text;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -23,6 +23,25 @@ public sealed class RibbonVerifier : Verifier
public const int MaxRibbonCount = (int)RibbonIndex.MAX_COUNT;
public override void Verify(LegalityAnalysis data)
{
Span<RibbonResult> result = stackalloc RibbonResult[MaxRibbonCount];
var count = Parse(result, data);
if (count == 0)
data.AddLine(GetValid(RibbonAllValid));
else // defer hint string creation unless we request the string. We'll re-do work, but this saves hot path allocation where the string is never needed to be humanized.
data.AddLine(GetInvalid(RibbonFInvalid_0, (ushort)count));
}
public static string GetMessage(LegalityAnalysis data, RibbonStrings str, LegalityCheckLocalization localize)
{
// Calling this method assumes that one or more ribbons are invalid or missing.
// The work was already done but forgotten, so we need to parse again.
Span<RibbonResult> result = stackalloc RibbonResult[MaxRibbonCount];
int count = Parse(result, data);
return GetMessage(result[..count], str, localize);
}
private static int Parse(Span<RibbonResult> result, LegalityAnalysis data)
{
// Flag VC (Gen1/2) ribbons using Gen7 origin rules.
var enc = data.EncounterMatch;
@ -30,16 +49,7 @@ public override void Verify(LegalityAnalysis data)
// Check Unobtainable Ribbons
var args = new RibbonVerifierArguments(pk, enc, data.Info.EvoChainsAllGens);
Span<RibbonResult> result = stackalloc RibbonResult[MaxRibbonCount];
int count = GetRibbonResults(args, result);
if (count == 0)
{
data.AddLine(GetValid(LRibbonAllValid));
return;
}
var msg = GetMessage(result[..count]);
data.AddLine(GetInvalid(msg));
return GetRibbonResults(args, result);
}
/// <summary>
@ -86,19 +96,19 @@ private static int GetRibbonResults(in RibbonVerifierArguments args, ref RibbonR
return list.Count;
}
private static string GetMessage(ReadOnlySpan<RibbonResult> result)
private static string GetMessage(ReadOnlySpan<RibbonResult> result, RibbonStrings str , LegalityCheckLocalization localize)
{
var total = result.Length;
int missing = GetCountMissing(result);
int invalid = total - missing;
var sb = new StringBuilder(total * 20);
if (missing != 0)
AppendAll(result, sb, LRibbonFMissing_0, true);
AppendAll(result, sb, str, localize.RibbonMissing_0, true);
if (invalid != 0)
{
if (missing != 0) // need to visually separate the message
sb.Append(Environment.NewLine);
AppendAll(result, sb, LRibbonFInvalid_0, false);
AppendAll(result, sb, str, localize.RibbonFInvalid_0, false);
}
return sb.ToString();
}
@ -116,7 +126,7 @@ private static int GetCountMissing(ReadOnlySpan<RibbonResult> result)
private const string MessageSplitNextRibbon = ", ";
private static void AppendAll(ReadOnlySpan<RibbonResult> result, StringBuilder sb, string startText, bool stateMissing)
private static void AppendAll(ReadOnlySpan<RibbonResult> result, StringBuilder sb, RibbonStrings str, string startText, bool stateMissing)
{
int added = 0;
sb.Append(startText);
@ -126,7 +136,7 @@ private static void AppendAll(ReadOnlySpan<RibbonResult> result, StringBuilder s
continue;
if (added++ != 0)
sb.Append(MessageSplitNextRibbon);
var localized = RibbonStrings.GetName(x.PropertyName);
var localized = str.GetName(x.PropertyName);
sb.Append(localized);
}
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.StorageSlotType;
using static PKHeX.Core.Species;
@ -18,12 +18,12 @@ public override void Verify(LegalityAnalysis data)
if (pk.IsEgg)
{
if (!IsSourceValidEgg(pk, source))
data.AddLine(GetInvalid(LStoredSourceEgg));
data.AddLine(GetInvalid(StoredSourceEgg));
}
else
{
if (!IsSourceValid(pk, source))
data.AddLine(GetInvalid(string.Format(LStoredSourceInvalid_0, source)));
data.AddLine(GetInvalid(StoredSlotSourceInvalid_0, (ushort)source));
}
}

View File

@ -1,4 +1,4 @@
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -23,7 +23,7 @@ public override void Verify(LegalityAnalysis data)
var id32 = pk.ID32;
if (id32 is 0 or int.MaxValue)
{
data.AddLine(GetInvalid(LOT_IDInvalid));
data.AddLine(GetInvalid(OT_IDInvalid));
return;
}
}
@ -45,29 +45,29 @@ public override void Verify(LegalityAnalysis data)
{
// Only TID is used for Gen 1/2 VC
if (pk.SID16 != 0)
data.AddLine(GetInvalid(LOT_SID0Invalid));
data.AddLine(GetInvalid(OT_SID0Invalid));
if (pk.TID16 == 0)
data.AddLine(Get(LOT_TID0, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_TID0));
return;
}
else if (pk.Format <= 2)
{
// Only TID is used for Gen 1/2
if (pk.TID16 == 0)
data.AddLine(Get(LOT_TID0, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_TID0));
return;
}
if (pk is { ID32: 0 })
data.AddLine(Get(LOT_IDs0, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_IDs0));
else if (pk.TID16 == pk.SID16)
data.AddLine(Get(LOT_IDEqual, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_IDEqual));
else if (pk.TID16 == 0)
data.AddLine(Get(LOT_TID0, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_TID0));
else if (pk.SID16 == 0)
data.AddLine(Get(LOT_SID0, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OT_SID0));
else if (IsOTIDSuspicious(pk.TID16, pk.SID16))
data.AddLine(Get(LOTSuspicious, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OTSuspicious));
}
public static bool TryGetShinySID(uint pid, ushort tid, GameVersion version, out ushort sid)
@ -97,13 +97,13 @@ public static bool TryGetShinySID(uint pid, ushort tid, GameVersion version, out
// japanese will stay Invalid
}
if (!MethodCXD.TryGetSeedTrainerID(tr.TID16, tr.SID16, out _))
data.AddLine(Get(LTrainerIDNoSeed, severity, CheckIdentifier.Trainer));
data.AddLine(Get(CheckIdentifier.Trainer, severity, TrainerIDNoSeed));
}
private static void VerifyTrainerID_RS<T>(LegalityAnalysis data, T tr, Severity severity = Severity.Invalid) where T : ITrainerID32ReadOnly
{
if (!MethodH.TryGetSeedTrainerID(tr.TID16, tr.SID16, out _))
data.AddLine(Get(LTrainerIDNoSeed, severity, CheckIdentifier.Trainer));
data.AddLine(Get(CheckIdentifier.Trainer, severity, TrainerIDNoSeed));
}
public static bool IsOTIDSuspicious(ushort tid16, ushort sid16) => (tid16, sid16) switch

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -27,19 +27,19 @@ public override void Verify(LegalityAnalysis data)
int len = pk.LoadString(pk.OriginalTrainerTrash, trainer);
if (len == 0)
{
data.AddLine(GetInvalid(LOTShort));
data.AddLine(GetInvalid(OTShort));
return;
}
trainer = trainer[..len];
if (trainer.Contains('\uffff') && pk is { Format: 4 })
{
data.AddLine(GetInvalid("Trainer Name: Unknown Character"));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, WordFilterInvalidCharacter_0, 0xFFFF));
return;
}
if (IsOTNameSuspicious(trainer))
{
data.AddLine(Get(LOTSuspicious, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OTSuspicious));
}
if (pk.VC)
@ -49,20 +49,20 @@ public override void Verify(LegalityAnalysis data)
else if (trainer.Length > Legal.GetMaxLengthOT(enc.Generation, (LanguageID)pk.Language))
{
if (!IsEdgeCaseLength(pk, enc, trainer))
data.AddLine(Get(LOTLong, Severity.Invalid));
data.AddLine(Get(Severity.Invalid, OTLong));
}
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format))
{
if (WordFilter.IsFiltered(trainer, out var badPattern, pk.Context, enc.Context))
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
if (WordFilter.IsFiltered(trainer, pk.Context, enc.Context, out var type, out var badPattern))
data.AddLine(GetInvalid(CheckIdentifier.Trainer, WordFilterFlaggedPattern_01, (ushort)type, (ushort)badPattern));
if (ContainsTooManyNumbers(trainer, enc.Generation))
data.AddLine(GetInvalid("Word Filter: Too many numbers."));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, WordFilterTooManyNumbers_0, (ushort)GetMaxNumberCount(enc.Generation)));
Span<char> ht = stackalloc char[pk.TrashCharCountTrainer];
int nameLen = pk.LoadString(pk.HandlingTrainerTrash, ht);
if (WordFilter.IsFiltered(ht[..nameLen], out badPattern, pk.Context)) // HT context is always the current context
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
if (WordFilter.IsFiltered(ht[..nameLen], pk.Context, out type, out badPattern)) // HT context is always the current context
data.AddLine(GetInvalid(CheckIdentifier.Handler, WordFilterFlaggedPattern_01, (ushort)type, (ushort)badPattern));
}
}
@ -104,7 +104,7 @@ public void VerifyOTGB(LegalityAnalysis data)
// Transferring from RBY->Gen7 won't have OT Gender in PK1, nor will PK1 originated encounters.
// GSC Trades already checked for OT Gender matching.
if (pk is { Format: > 2, VC1: true } || enc is { Generation: 1 } or EncounterGift2 { IsEgg: false })
data.AddLine(GetInvalid(LG1OTGender));
data.AddLine(GetInvalid(G1OTGender));
}
if (enc is IFixedTrainer { IsFixedTrainer: true })
@ -118,11 +118,11 @@ public void VerifyOTGB(LegalityAnalysis data)
{
if (pk is SK2 {TID16: 0, IsRental: true})
{
data.AddLine(Get(LOTShort, Severity.Fishy));
data.AddLine(Get(Severity.Fishy, OTShort));
}
else
{
data.AddLine(GetInvalid(LOTShort));
data.AddLine(GetInvalid(OTShort));
return;
}
}
@ -145,23 +145,23 @@ private void VerifyGBOTWithinBounds(LegalityAnalysis data, ReadOnlySpan<char> st
if (pk.Japanese)
{
if (str.Length > 5)
data.AddLine(GetInvalid(LOTLong));
data.AddLine(GetInvalid(OTLong, 5));
if (!StringConverter1.GetIsJapanese(str))
data.AddLine(GetInvalid(LG1CharOT));
data.AddLine(GetInvalid(G1CharOT));
}
else if (pk.Korean)
{
if (str.Length > 5)
data.AddLine(GetInvalid(LOTLong));
data.AddLine(GetInvalid(OTLong, 5));
if (!StringConverter2KOR.GetIsKorean(str))
data.AddLine(GetInvalid(LG1CharOT));
data.AddLine(GetInvalid(G1CharOT));
}
else
{
if (str.Length > 7)
data.AddLine(GetInvalid(LOTLong));
data.AddLine(GetInvalid(OTLong, 7));
if (!StringConverter1.GetIsEnglish(str))
data.AddLine(GetInvalid(LG1CharOT));
data.AddLine(GetInvalid(G1CharOT));
}
}
@ -179,13 +179,15 @@ public static bool ContainsTooManyNumbers(ReadOnlySpan<char> str, byte originalG
{
if (originalGeneration <= 3)
return false; // no limit from these generations
int max = originalGeneration < 6 ? 4 : 5;
int max = GetMaxNumberCount(originalGeneration);
if (str.Length <= max)
return false;
int count = GetNumberCount(str);
return count > max;
}
public static int GetMaxNumberCount(byte originalGeneration) => originalGeneration < 6 ? 4 : 5;
private static int GetNumberCount(ReadOnlySpan<char> str)
{
int ctr = 0;

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
namespace PKHeX.Core;
@ -27,7 +27,7 @@ private void VerifyVCOTGender(LegalityAnalysis data)
{
var pk = data.Entity;
if (pk.OriginalTrainerGender == 1 && pk.Version != GameVersion.C)
data.AddLine(GetInvalid(LG2OTGender));
data.AddLine(GetInvalid(G2OTGender));
}
private void VerifyVCNatureEXP(LegalityAnalysis data)
@ -39,7 +39,7 @@ private void VerifyVCNatureEXP(LegalityAnalysis data)
{
var nature = Experience.GetNatureVC(pk.EXP);
if (nature != pk.Nature)
data.AddLine(GetInvalid(LTransferNature));
data.AddLine(GetInvalid(TransferNature, (uint)nature));
return;
}
if (met <= 2) // Not enough EXP to have every nature -- check for exclusions!
@ -49,7 +49,7 @@ private void VerifyVCNatureEXP(LegalityAnalysis data)
var nature = pk.Nature;
bool valid = VerifyVCNature(growth, nature);
if (!valid)
data.AddLine(GetInvalid(LTransferNature));
data.AddLine(GetInvalid(TransferNature));
}
}
@ -68,7 +68,7 @@ private static void VerifyVCShinyXorIfShiny(LegalityAnalysis data)
// (15:65536, ~1:4096) odds on a given shiny transfer!
var xor = data.Entity.ShinyXor;
if (xor is <= 15 and not 0)
data.AddLine(Get(LEncStaticPIDShiny, ParseSettings.Settings.Game.Gen7.Gen7TransferStarPID, CheckIdentifier.PID));
data.AddLine(Get(CheckIdentifier.PID, ParseSettings.Settings.Game.Gen7.Gen7TransferStarPID, EncStaticPIDShiny));
}
private static void VerifyVCGeolocation(LegalityAnalysis data)
@ -79,7 +79,7 @@ private static void VerifyVCGeolocation(LegalityAnalysis data)
// VC Games were region locked to the Console, meaning not all language games are available.
var within = Locale3DS.IsRegionLockedLanguageValidVC(pk7.ConsoleRegion, pk7.Language);
if (!within)
data.AddLine(GetInvalid(string.Format(LOTLanguage, $"!={(LanguageID)pk7.Language}", ((LanguageID)pk7.Language).ToString()), CheckIdentifier.Language));
data.AddLine(GetInvalid(CheckIdentifier.Language, OTLanguageCannotTransferToConsoleRegion_0, pk7.ConsoleRegion));
}
public void VerifyTransferLegalityG3(LegalityAnalysis data)
@ -88,12 +88,12 @@ public void VerifyTransferLegalityG3(LegalityAnalysis data)
if (pk.Format == 4) // Pal Park (3->4)
{
if (pk.MetLocation != Locations.Transfer3)
data.AddLine(GetInvalid(LEggLocationPalPark));
data.AddLine(GetInvalid(EggLocationPalPark, Locations.Transfer3));
}
else // Transporter (4->5)
{
if (pk.MetLocation != Locations.Transfer4)
data.AddLine(GetInvalid(LTransferEggLocationTransporter));
data.AddLine(GetInvalid(TransferEggLocationTransporter, Locations.Transfer4));
}
}
@ -109,14 +109,14 @@ public void VerifyTransferLegalityG4(LegalityAnalysis data)
{
case (int)Species.Celebi:
if (loc is not (Locations.Transfer4_CelebiUnused or Locations.Transfer4_CelebiUsed))
data.AddLine(GetInvalid(LTransferMet));
data.AddLine(GetInvalid(TransferMet));
break;
case (int)Species.Raikou or (int)Species.Entei or (int)Species.Suicune:
if (loc is not (Locations.Transfer4_CrownUnused or Locations.Transfer4_CrownUsed))
data.AddLine(GetInvalid(LTransferMet));
data.AddLine(GetInvalid(TransferMet));
break;
default:
data.AddLine(GetInvalid(LTransferEggLocationTransporter));
data.AddLine(GetInvalid(TransferEggLocationTransporter));
break;
}
}
@ -137,7 +137,7 @@ public void VerifyTransferLegalityG8(LegalityAnalysis data)
{
if (s.IsTotemNoTransfer || pk.Form != s.GetTotemBaseForm())
{
data.AddLine(GetInvalid(LTransferBad));
data.AddLine(GetInvalid(TransferBad));
return;
}
}
@ -152,7 +152,7 @@ public void VerifyTransferLegalityG8(LegalityAnalysis data)
_ => PersonalTable.SWSH,
};
if (!pt.IsPresentInGame(pk.Species, pk.Form))
data.AddLine(GetInvalid(LTransferBad));
data.AddLine(GetInvalid(TransferBad));
}
private void VerifyHOMETransfer(LegalityAnalysis data, PKM pk)
@ -168,7 +168,7 @@ private void VerifyHOMETransfer(LegalityAnalysis data, PKM pk)
if (pk.Context is not (EntityContext.Gen8 or EntityContext.Gen8a or EntityContext.Gen8b))
{
if (s is { HeightScalar: 0, WeightScalar: 0 } && !data.Info.EvoChainsAllGens.HasVisitedPLA)
data.AddLine(GetInvalid(LTransferBad));
data.AddLine(GetInvalid(TransferBad));
}
}
@ -178,7 +178,7 @@ private void VerifyHOMETracker(LegalityAnalysis data, PKM pk)
// Can't validate the actual values (we aren't the server), so we can only check against zero.
if (pk is IHomeTrack { HasTracker: false })
{
data.AddLine(Get(LTransferTrackerMissing, ParseSettings.Settings.HOMETransfer.HOMETransferTrackerNotPresent));
data.AddLine(Get(ParseSettings.Settings.HOMETransfer.HOMETransferTrackerNotPresent, TransferTrackerMissing));
// To the reader: It seems like the best course of action for setting a tracker is:
// - Transfer a 0-Tracker pk to HOME to get assigned a valid Tracker via the game it originated from.
// - Don't make one up.
@ -188,11 +188,11 @@ private void VerifyHOMETracker(LegalityAnalysis data, PKM pk)
public void VerifyVCEncounter(PKM pk, IEncounterTemplate original, EncounterTransfer7 transfer, LegalityAnalysis data)
{
if (pk.MetLocation != transfer.Location)
data.AddLine(GetInvalid(LTransferMetLocation));
data.AddLine(GetInvalid(TransferMetLocation));
var expectEgg = pk is PB8 ? Locations.Default8bNone : transfer.EggLocation;
if (pk.EggLocation != expectEgg)
data.AddLine(GetInvalid(LEggLocationNone));
data.AddLine(GetInvalid(EggLocationNone));
// Flag Moves that cannot be transferred
if (original is EncounterStatic2 { DizzyPunchEgg: true}) // Dizzy Punch Gifts
@ -207,12 +207,12 @@ public void VerifyVCEncounter(PKM pk, IEncounterTemplate original, EncounterTran
var enc = data.EncounterOriginal;
var pi = PersonalTable.USUM[enc.Species];
if (pi.Gender == 31 && pk.IsShiny) // impossible gender-shiny
data.AddLine(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.PID));
data.AddLine(GetInvalid(CheckIdentifier.PID, EncStaticPIDShiny));
}
else if (pk.Species == (int)Species.Unown)
{
if (pk.Form is not (8 or 21) && pk.IsShiny) // impossibly form-shiny (not I or V)
data.AddLine(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.PID));
data.AddLine(GetInvalid(CheckIdentifier.PID, EncStaticPIDShiny));
}
}

View File

@ -1,5 +1,5 @@
using System;
using static PKHeX.Core.LegalityCheckStrings;
using static PKHeX.Core.LegalityCheckResultCode;
using static PKHeX.Core.StringSource;
namespace PKHeX.Core;
@ -11,16 +11,6 @@ public sealed class TrashByteVerifier : Verifier
{
protected override CheckIdentifier Identifier => CheckIdentifier.TrashBytes;
private static string Format(StringSource s) => s switch
{
Nickname => L_XNickname,
OriginalTrainer => L_XOT,
HandlingTrainer => L_XHT,
_ => throw new ArgumentOutOfRangeException(nameof(s)),
};
private static string Format(StringSource s, string msg) => string.Format(L_F0_1, Format(s), msg);
public override void Verify(LegalityAnalysis data)
{
var pk = data.Entity;
@ -38,19 +28,19 @@ public override void Verify(LegalityAnalysis data)
}
}
private void VerifyTrashBytesPalPark(LegalityAnalysis data, PKM pk)
private static void VerifyTrashBytesPalPark(LegalityAnalysis data, PKM pk)
{
if (pk.Japanese)
{
// Trash bytes should be zero.
if (!TrashBytesUTF16.IsTrashEmpty(pk.OriginalTrainerTrash))
data.AddLine(GetInvalid(Format(Nickname, LTrashBytesShouldBeEmpty)));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, TrashBytesShouldBeEmpty));
}
else
{
// Should have trash bytes from the transfer process.
if (TrashBytesUTF16.IsTrashEmpty(pk.OriginalTrainerTrash))
data.AddLine(GetInvalid(Format(Nickname, LTrashBytesExpected)));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, TrashBytesExpected));
}
}
@ -59,24 +49,24 @@ private void VerifyTrashBytesPCD(LegalityAnalysis data, PKM pk, PCD pcd)
var enc = pcd.Gift.PK;
var ot = enc.OriginalTrainerTrash;
if (!ot.SequenceEqual(pk.OriginalTrainerTrash))
data.AddLine(GetInvalid(Format(OriginalTrainer, LTrashBytesMismatchInitial)));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, TrashBytesMismatchInitial));
if (pcd.Species != pk.Species)
return; // Evolved, trash bytes are rewritten.
var nick = enc.NicknameTrash;
if (!nick.SequenceEqual(pk.NicknameTrash))
data.AddLine(GetInvalid(Format(Nickname, LTrashBytesMismatchInitial)));
data.AddLine(GetInvalid(CheckIdentifier.Nickname, TrashBytesMismatchInitial));
}
private void VerifyTrashBytesHOME(LegalityAnalysis data, PKM pk)
{
if (!TrashBytesUTF16.IsFinalTerminatorPresent(pk.NicknameTrash))
data.AddLine(GetInvalid(Format(Nickname, LTrashBytesMissingTerminator)));
data.AddLine(GetInvalid(CheckIdentifier.Nickname, TrashBytesMissingTerminator));
if (!TrashBytesUTF16.IsFinalTerminatorPresent(pk.OriginalTrainerTrash))
data.AddLine(GetInvalid(Format(OriginalTrainer, LTrashBytesMissingTerminator)));
data.AddLine(GetInvalid(CheckIdentifier.Trainer, TrashBytesMissingTerminator));
if (!TrashBytesUTF16.IsFinalTerminatorPresent(pk.HandlingTrainerTrash))
data.AddLine(GetInvalid(Format(HandlingTrainer, LTrashBytesMissingTerminator)));
data.AddLine(GetInvalid(CheckIdentifier.Handler, TrashBytesMissingTerminator));
if (pk.IsEgg)
{
@ -143,15 +133,14 @@ private void VerifyTrashSingle(LegalityAnalysis data, ReadOnlySpan<byte> span, S
{
var result = TrashBytesUTF16.IsTrashSingleOrNone(span);
if (result.IsInvalid())
data.AddLine(GetInvalid(Format(s, LTrashBytesShouldBeEmpty)));
data.AddLine(GetInvalid(GetIdentifier(s), TrashBytesShouldBeEmpty));
}
private void VerifyTrashSpecific(LegalityAnalysis data, ReadOnlySpan<byte> span, ReadOnlySpan<char> under, StringSource s,
Severity severity = Severity.Invalid)
private void VerifyTrashSpecific(LegalityAnalysis data, ReadOnlySpan<byte> span, ReadOnlySpan<char> under, StringSource s, Severity severity = Severity.Invalid)
{
var result = TrashBytesUTF16.IsTrashSpecific(span, under);
if (result.IsInvalid())
data.AddLine(Get(Format(s, string.Format(LTrashBytesExpected_0, under.ToString())), severity));
data.AddLine(Get(GetIdentifier(s), severity, TrashBytesExpected));
}
private void VerifyTrashNone(LegalityAnalysis data, ReadOnlySpan<byte> span, StringSource s,
@ -159,20 +148,28 @@ private void VerifyTrashSingle(LegalityAnalysis data, ReadOnlySpan<byte> span, S
{
var result = TrashBytesUTF16.IsTrashNone(span);
if (result.IsInvalid())
data.AddLine(Get(Format(s, LTrashBytesShouldBeEmpty), severity));
data.AddLine(Get(GetIdentifier(s), severity, TrashBytesShouldBeEmpty));
}
private void VerifyTrashNotEmpty(LegalityAnalysis data, ReadOnlySpan<byte> span, StringSource s)
{
if (!TrashBytesUTF16.IsTrashNotEmpty(span))
data.AddLine(GetInvalid(Format(s, LTrashBytesExpected)));
data.AddLine(GetInvalid(GetIdentifier(s), TrashBytesExpected));
}
private void VerifyTrashEmpty(LegalityAnalysis data, ReadOnlySpan<byte> span, StringSource s)
{
if (!TrashBytesUTF16.IsTrashEmpty(span))
data.AddLine(GetInvalid(Format(s, LTrashBytesShouldBeEmpty)));
data.AddLine(GetInvalid(GetIdentifier(s), TrashBytesShouldBeEmpty));
}
private static CheckIdentifier GetIdentifier(StringSource s) => s switch
{
Nickname => CheckIdentifier.Nickname,
OriginalTrainer => CheckIdentifier.Trainer,
HandlingTrainer => CheckIdentifier.Handler,
_ => throw new ArgumentOutOfRangeException(nameof(s)),
};
}
public enum StringSource : byte { Nickname, OriginalTrainer, HandlingTrainer }

View File

@ -16,11 +16,19 @@ public abstract class Verifier
/// <param name="data">Analysis data to process</param>
public abstract void Verify(LegalityAnalysis data);
protected CheckResult GetInvalid(string msg) => Get(msg, Severity.Invalid);
protected CheckResult GetValid(string msg) => Get(msg, Severity.Valid);
protected CheckResult Get(string msg, Severity s) => new(s, Identifier, msg);
// Standard methods for creating CheckResults
protected CheckResult GetValid(LegalityCheckResultCode msg) => Get(Severity.Valid, msg);
protected CheckResult GetInvalid(LegalityCheckResultCode msg) => Get(Severity.Invalid, msg);
protected CheckResult Get(Severity s, LegalityCheckResultCode msg) => CheckResult.Get(s, Identifier, msg);
protected static CheckResult GetInvalid(string msg, CheckIdentifier c) => Get(msg, Severity.Invalid, c);
protected static CheckResult GetValid(string msg, CheckIdentifier c) => Get(msg, Severity.Valid, c);
protected static CheckResult Get(string msg, Severity s, CheckIdentifier c) => new(s, c, msg);
protected CheckResult GetValid(LegalityCheckResultCode msg, uint argument) => Get(Severity.Valid, msg, argument);
protected CheckResult GetInvalid(LegalityCheckResultCode msg, uint argument) => Get(Severity.Invalid, msg, argument);
protected CheckResult GetInvalid(LegalityCheckResultCode msg, ushort arg0, ushort arg1) => GetInvalid(Identifier, msg, arg0, arg1);
protected CheckResult Get(Severity s, LegalityCheckResultCode msg, uint argument) => CheckResult.Get(s, Identifier, msg, argument);
protected static CheckResult GetValid(CheckIdentifier c, LegalityCheckResultCode msg, uint argument = 0) => Get(c, Severity.Valid, msg, argument);
protected static CheckResult Get(CheckIdentifier c, Severity s, LegalityCheckResultCode msg, uint argument = 0) => CheckResult.Get(s, c, msg, argument);
protected static CheckResult GetInvalid(CheckIdentifier c, LegalityCheckResultCode msg, uint value = 0) => CheckResult.Get(Severity.Invalid, c, msg, value);
protected static CheckResult GetInvalid(CheckIdentifier c, LegalityCheckResultCode msg, ushort arg0, ushort arg1 = 0) => GetInvalid(c, msg, arg0 | (uint)arg1 << 16);
}

View File

@ -1,423 +0,0 @@
L_AError = Internal error.
L_ALegal = Legal!
L_AnalysisUnavailable = Analysis not available for this Pokémon.
L_AValid = Valid.
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} Move {1}: {2}
L_F0_RM_1_2 = {0} Relearn Move {1}: {2}
L_FEncounterType_0 = Encounter Type: {0}
L_FOriginSeed_0 = Origin Seed: {0}
L_FPIDType_0 = PID Type: {0}
L_SFishy = Fishy
L_SInvalid = Invalid
L_SNotImplemented = Not Implemented
L_SValid = Valid
L_XEnigmaBerry_0 = {0}BEERE
L_XHT = HT
L_XKorean = Korean
L_XKoreanNon = Non-Korean
L_XLocation = Location
L_XMatches0_1 = Matches: {0} {1}
L_XNickname = Nickname
L_XOT = OT
L_XRareFormEvo_0_1 = Evolves into form: {0} (rare: {1})
L_XWurmpleEvo_0 = Wurmple Evolution: {0}
LAbilityCapsuleUsed = Ability available with Ability Capsule.
LAbilityFlag = Ability matches ability number.
LAbilityHiddenFail = Hidden Ability mismatch for encounter type.
LAbilityHiddenUnavailable = Hidden Ability not available.
LAbilityMismatch = Ability mismatch for encounter.
LAbilityMismatch3 = Ability does not match Generation 3 species ability.
LAbilityMismatchFlag = Ability does not match ability number.
LAbilityMismatchGift = Ability does not match Mystery Gift.
LAbilityMismatchGrotto = Hidden Grotto captures should have Hidden Ability.
LAbilityMismatchHordeSafari = Hidden Ability on non-horde/friend safari wild encounter.
LAbilityMismatchPID = Ability does not match PID.
LAbilityMismatchSOS = Hidden Ability on non-SOS wild encounter.
LAbilityPatchRevertUsed = Ability available with Ability Patch Revert.
LAbilityPatchUsed = Ability available with Ability Patch.
LAbilityUnexpected = Ability is not valid for species/form.
LAwakenedCap = Individual AV cannot be greater than {0}.
LAwakenedShouldBeValue = Individual AV ({1}) should be greater than {0}.
LBallAbility = Can't obtain Hidden Ability with Ball.
LBallEggCherish = Can't have Cherish Ball for regular Egg.
LBallEggMaster = Can't have Master Ball for regular Egg.
LBallEnc = Correct ball for encounter type.
LBallEncMismatch = Can't have ball for encounter type.
LBallHeavy = Can't have Heavy Ball for light, low-catch rate species (Gen VII).
LBallNone = No check satisfied, assuming illegal.
LBallSpecies = Can't obtain species in Ball.
LBallSpeciesPass = Ball possible for species.
LBallUnavailable = Ball unobtainable in origin Generation.
LContestSheenTooHigh_0 = Contest Stat Sheen should be <= {0}.
LContestSheenTooLow_0 = Contest Stat Sheen should be >= {0}.
LContestZero = Contest Stats should be 0.
LContestZeroSheen = Contest Stat Sheen should be 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = Met Date is outside of distribution window.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 2 EVs remaining.
LEffortAbove252 = EVs cannot go above 252.
LEffortAbove510 = EV total cannot be above 510.
LEffortAllEqual = EVs are all equal.
LEffortCap100 = Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100.
LEffortEgg = Eggs cannot receive EVs.
LEffortEXPIncreased = All EVs are zero, but leveled above Met Level.
LEffortShouldBeZero = Cannot receive EVs.
LEffortUntrainedCap = Individual EV without changing EXP cannot be greater than {0}.
LEggContest = Cannot increase Contest Stats of an Egg.
LEggEXP = Eggs cannot receive experience.
LEggFMetLevel_0 = Invalid Met Level, expected {0}.
LEggHatchCycles = Invalid Egg hatch cycles.
LEggLocation = Able to hatch an Egg at Met Location.
LEggLocationInvalid = Can't hatch an Egg at Met Location.
LEggLocationNone = Invalid Egg Location, expected none.
LEggLocationPalPark = Invalid Met Location, expected Pal Park.
LEggLocationTrade = Able to hatch a traded Egg at Met Location.
LEggLocationTradeFail = Invalid Egg Location, shouldn't be 'traded' while an Egg.
LEggMetLocationFail = Can't obtain Egg from Egg Location.
LEggNature = Eggs cannot have their Stat Nature changed.
LEggPokeathlon = Eggs cannot have Pokéathlon stats.
LEggPokerus = Eggs can not be infected with Pokérus.
LEggPP = Eggs cannot have modified PP counts.
LEggPPUp = Cannot apply PP Ups to an Egg.
LEggRelearnFlags = Expected no Relearn Move Flags.
LEggShinyLeaf = Eggs cannot have Shiny Leaf/Crown.
LEggShinyPokeStar = Eggs cannot be a Pokéstar Studios star.
LEggSpecies = Can't obtain Egg for this species.
LEggUnhatched = Valid un-hatched Egg.
LEncCondition = Valid Wild Encounter at location.
LEncConditionBadRNGFrame = Unable to match encounter conditions to a possible RNG frame.
LEncConditionBadSpecies = Species does not exist in origin game.
LEncConditionBlack = Valid Wild Encounter at location (Black Flute).
LEncConditionBlackLead = Valid Wild Encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).
LEncConditionDexNav = Valid Wild Encounter at location (DexNav).
LEncConditionLead = Valid Wild Encounter at location (Pressure/Hustle/Vital Spirit).
LEncConditionWhite = Valid Wild Encounter at location (White Flute).
LEncConditionWhiteLead = Valid Wild Encounter at location (White Flute & Pressure/Hustle/Vital Spirit).
LEncGift = Unable to match a gift Egg encounter from origin game.
LEncGiftEggEvent = Unable to match an event Egg encounter from origin game.
LEncGiftIVMismatch = IVs do not match Mystery Gift Data.
LEncGiftNicknamed = Event gift has been nicknamed.
LEncGiftNotFound = Unable to match to a Mystery Gift in the database.
LEncGiftPIDMismatch = Mystery Gift fixed PID mismatch.
LEncGiftShinyMismatch = Mystery Gift shiny mismatch.
LEncGiftVersionNotDistributed = Mystery Gift cannot be received by this version.
LEncInvalid = Unable to match an encounter from origin game.
LEncMasteryInitial = Initial move mastery flags do not match the encounter's expected state.
LEncStaticMatch = Valid gift/static encounter.
LEncStaticPIDShiny = Static Encounter shiny mismatch.
LEncStaticRelearn = Static encounter relearn move mismatch.
LEncTradeChangedNickname = In-game Trade Nickname has been altered.
LEncTradeChangedOT = In-game Trade OT has been altered.
LEncTradeIndexBad = In-game Trade invalid index?
LEncTradeMatch = Valid in-game trade.
LEncTradeUnchanged = In-game Trade OT and Nickname have not been altered.
LEncTypeMatch = Encounter Type matches encounter.
LEncTypeMismatch = Encounter Type does not match encounter.
LEncUnreleased = Unreleased event.
LEncUnreleasedEMewJP = Non Japanese Mew from Faraway Island. Unreleased event.
LEncUnreleasedHoOArceus = Arceus from Hall of Origin. Unreleased event.
LEncUnreleasedPtDarkrai = Non Platinum Darkrai from Newmoon Island. Unreleased event.
LEncUnreleasedPtShaymin = Non Platinum Shaymin from Flower Paradise. Unreleased event.
LEReaderAmerica = American E-Reader Berry in Japanese save file.
LEReaderInvalid = Invalid E-Reader Berry.
LEReaderJapan = Japanese E-Reader Berry in international save file.
LEvoInvalid = Evolution not valid (or level/trade evolution unsatisfied).
LEvoTradeReq = In-game trade {0} should have evolved into {1}.
LEvoTradeReqOutsider = Outsider {0} should have evolved into {1}.
LEvoTradeRequired = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.
LFateful = Special in-game Fateful Encounter.
LFatefulGiftMissing = Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?
LFatefulInvalid = Fateful Encounter should not be checked.
LFatefulMissing = Special in-game Fateful Encounter flag missing.
LFatefulMystery = Mystery Gift Fateful Encounter.
LFatefulMysteryMissing = Mystery Gift Fateful Encounter flag missing.
LFavoriteMarkingUnavailable = Favorite Marking is not available.
LFormArgumentHigh = Form argument is too high for current form.
LFormArgumentInvalid = Form argument is not valid.
LFormArgumentLow = Form argument is too low for current form.
LFormArgumentNotAllowed = Form argument is not allowed for this encounter.
LFormArgumentValid = Form argument is valid.
LFormBattle = Form cannot exist outside of a battle.
LFormEternal = Valid Eternal Flower encounter.
LFormEternalInvalid = Invalid Eternal Flower encounter.
LFormInvalidExpect_0 = Form is invalid, expected form index {0}.
LFormInvalidGame = Form cannot be obtained in origin game.
LFormInvalidNature = Form cannot have this nature.
LFormInvalidRange = Form Count is out of range. Expected <= {0}, got {1}.
LFormItem = Held item matches Form.
LFormItemInvalid = Held item does not match Form.
LFormParty = Form cannot exist outside of Party.
LFormPikachuCosplay = Only Cosplay Pikachu can have this form.
LFormPikachuCosplayInvalid = Cosplay Pikachu cannot have the default form.
LFormPikachuEventInvalid = Event Pikachu cannot have the default form.
LFormValid = Form is Valid.
LFormVivillon = Valid Vivillon pattern.
LFormVivillonEventPre = Event Vivillon pattern on pre-evolution.
LFormVivillonInvalid = Invalid Vivillon pattern.
LFormVivillonNonNative = Non-native Vivillon pattern.
LG1CatchRateChain = Catch rate does not match any species from Pokémon evolution chain.
LG1CatchRateEvo = Catch rate match species without encounters. Expected a preevolution catch rate.
LG1CatchRateItem = Catch rate does not match a valid held item from Generation 2.
LG1CatchRateMatchPrevious = Catch Rate matches any species from Pokémon evolution chain.
LG1CatchRateMatchTradeback = Catch rate matches a valid held item from Generation 2.
LG1CatchRateNone = Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items.
LG1CharNick = Nickname from Generation 1/2 uses unavailable characters.
LG1CharOT = OT from Generation 1/2 uses unavailable characters.
LG1GBEncounter = Can't obtain Special encounter in Virtual Console games.
LG1MoveExclusive = Generation 1 exclusive move. Incompatible with Non-tradeback moves.
LG1MoveLearnSameLevel = Incompatible moves. Learned at the same level in Red/Blue and Yellow.
LG1MoveTradeback = Non-tradeback Egg move. Incompatible with Generation 1 exclusive moves.
LG1OTEvent = Incorrect RBY event OT Name.
LG1OTGender = Female OT from Generation 1/2 is invalid.
LG1Stadium = Incorrect Stadium OT.
LG1StadiumInternational = Valid International Stadium OT.
LG1StadiumJapanese = Valid Japanese Stadium OT.
LG1TradebackPreEvoMove = Non-tradeback pre evolution move. Incompatible with Generation 1 exclusive moves.
LG1Type1Fail = Invalid Type A, does not match species type.
LG1Type2Fail = Invalid Type B, does not match species type.
LG1TypeMatch1 = Valid Type A, matches species type.
LG1TypeMatch2 = Valid Type B, matches species type.
LG1TypeMatchPorygon = Porygon with valid Type A and B values.
LG1TypePorygonFail = Porygon with invalid Type A and B values. Does not a match a valid type combination.
LG1TypePorygonFail1 = Porygon with invalid Type A value.
LG1TypePorygonFail2 = Porygon with invalid Type B value.
LG2InvalidTilePark = National Park fishing encounter. Unreachable Water tiles.
LG2InvalidTileR14 = Kanto Route 14 fishing encounter. Unreachable Water tiles.
LG2InvalidTileSafari = Generation 2 Safari Zone fishing encounter. Unreachable zone.
LG2InvalidTileTreeID = Found an unreachable tree for Crystal headbutt encounter that matches OTID.
LG2InvalidTileTreeNotFound = Could not find a tree for Crystal headbutt encounter that matches OTID.
LG2OTGender = OT from Virtual Console games other than Crystal cannot be female.
LG2TreeID = Found a tree for Crystal headbutt encounter that matches OTID.
LG3EReader = Non Japanese Shadow E-reader Pokémon. Unreleased encounter.
LG3OTGender = OT from Colosseum/XD cannot be female.
LG4InvalidTileR45Surf = Johto Route 45 surfing encounter. Unreachable Water tiles.
LG5ID_N = The Name/TID16/SID16 of N is incorrect.
LG5IVAll30 = All IVs of N's Pokémon should be 30.
LG5OTGenderN = N's Pokémon must have a male OT gender.
LG5PIDShinyGrotto = Hidden Grotto captures cannot be shiny.
LG5PIDShinyN = N's Pokémon cannot be shiny.
LG5SparkleInvalid = Special in-game N's Sparkle flag should not be checked.
LG5SparkleRequired = Special in-game N's Sparkle flag missing.
LGanbaruStatTooHigh = One or more Ganbaru Value is above the natural limit of (10 - IV bonus).
LGenderInvalidNone = Genderless Pokémon should not have a gender.
LGeoBadOrder = GeoLocation Memory: Gap/Blank present.
LGeoHardwareInvalid = Geolocation: Country is not in 3DS region.
LGeoHardwareRange = Invalid Console Region.
LGeoHardwareValid = Geolocation: Country is in 3DS region.
LGeoMemoryMissing = GeoLocation Memory: Memories should be present.
LGeoNoCountryHT = GeoLocation Memory: HT Name present but has no previous Country.
LGeoNoRegion = GeoLocation Memory: Region without Country.
LHyperPerfectAll = Can't Hyper Train a Pokémon with perfect IVs.
LHyperPerfectOne = Can't Hyper Train a perfect IV.
LHyperPerfectUnavailable = Can't Hyper Train any IV(s).
LHyperTooLow_0 = Can't Hyper Train a Pokémon that isn't level {0}.
LItemEgg = Eggs cannot hold items.
LItemUnreleased = Held item is unreleased.
LIVAllEqual_0 = All IVs are {0}.
LIVF_COUNT0_31 = Should have at least {0} IVs = 31.
LIVNotCorrect = IVs do not match encounter requirements.
LLevelEXPThreshold = Current experience matches level threshold.
LLevelEXPTooHigh = Current experience exceeds maximum amount for level 100.
LLevelMetBelow = Current level is below met level.
LLevelMetGift = Met Level does not match Mystery Gift level.
LLevelMetGiftFail = Current Level below Mystery Gift level.
LLevelMetSane = Current level is not below met level.
LMarkValueOutOfRange_0 = Individual marking at index {0} is not within the allowed value range.
LMarkValueShouldBeZero = Marking flags cannot be set.
LMarkValueUnusedBitsPresent = Marking flags uses bits beyond the accessible range.
LMemoryArgBadCatch = {0} Memory: {0} did not catch this.
LMemoryArgBadHatch = {0} Memory: {0} did not hatch this.
LMemoryArgBadHT = Memory: Can't have Handling Trainer Memory as Egg.
LMemoryArgBadID = {0} Memory: Can't obtain Memory on {0} Version.
LMemoryArgBadItem = {0} Memory: Species can't hold this item.
LMemoryArgBadLocation = {0} Memory: Can't obtain Location on {0} Version.
LMemoryArgBadMove = {0} Memory: Species can't learn this move.
LMemoryArgBadOTEgg = {0} Memory: Link Trade is not a valid first memory.
LMemoryArgBadSpecies = {0} Memory: Can't capture species in game.
LMemoryArgSpecies = {0} Memory: Species can be captured in game.
LMemoryCleared = Memory: Not cleared properly.
LMemoryF_0_Valid = {0} Memory is valid.
LMemoryFeelInvalid = {0} Memory: Invalid Feeling.
LMemoryHTFlagInvalid = Untraded: Current handler should not be the Handling Trainer.
LMemoryHTGender = HT Gender invalid: {0}
LMemoryHTLanguage = HT Language is missing.
LMemoryIndexArgHT = Should have a HT Memory TextVar value (somewhere).
LMemoryIndexFeel = {0} Memory: Feeling should be index {1}.
LMemoryIndexFeelHT09 = Should have a HT Memory Feeling value 0-9.
LMemoryIndexID = {0} Memory: Should be index {1}.
LMemoryIndexIntensity = {0} Memory: Intensity should be index {1}.
LMemoryIndexIntensityHT1 = Should have a HT Memory Intensity value (1st).
LMemoryIndexIntensityMin = {0} Memory: Intensity should be at least {1}.
LMemoryIndexLinkHT = Should have a Link Trade HT Memory.
LMemoryIndexVar = {0} Memory: TextVar should be index {1}.
LMemoryMissingHT = Memory: Handling Trainer Memory missing.
LMemoryMissingOT = Memory: Original Trainer Memory missing.
LMemorySocialTooHigh_0 = Social Stat should be <= {0}
LMemorySocialZero = Social Stat should be zero.
LMemoryStatAffectionHT0 = Untraded: Handling Trainer Affection should be 0.
LMemoryStatAffectionOT0 = OT Affection should be 0.
LMemoryStatEnjoyment = Enjoyment should be {0}.
LMemoryStatFriendshipHT0 = Untraded: Handling Trainer Friendship should be 0.
LMemoryStatFriendshipOTBaseEvent = Event OT Friendship does not match base friendship.
LMemoryStatFullness = Fullness should be {0}.
LMetDetailTimeOfDay = Met Time of Day value is not within the expected range.
LMoveEggFIncompatible0_1 = {0} Inherited Move. Incompatible with {1} inherited moves.
LMoveEggIncompatible = Egg Move. Incompatible with event Egg moves.
LMoveEggIncompatibleEvent = Event Egg Move. Incompatible with normal Egg moves.
LMoveEggInherited = Inherited Egg move.
LMoveEggInheritedTutor = Inherited tutor move.
LMoveEggInvalid = Not an expected Egg move.
LMoveEggInvalidEvent = Egg Move.Not expected in an event Egg.
LMoveEggInvalidEventLevelUp = Inherited move learned by Level-up.Not expected in an event Egg.
LMoveEggInvalidEventLevelUpGift = Inherited move learned by Level-up. Not expected in a gift Egg.
LMoveEggInvalidEventTMHM = Inherited TM/HM move. Not expected in an event Egg.
LMoveEggInvalidEventTutor = Inherited tutor move. Not expected in an event Egg.
LMoveEggLevelUp = Inherited move learned by Level-up.
LMoveEggMissing = Event Egg move missing.
LMoveEggMoveGift = Egg Move. Not expected in a gift Egg.
LMoveEggTMHM = Inherited TM/HM move.
LMoveEventEggLevelUp = Inherited move learned by Level-up. Incompatible with event Egg moves.
LMoveEvoFCombination_0 = Moves combinations is not compatible with {0} evolution.
LMoveEvoFHigher = Incompatible evolution moves. {1} Move learned at a higher level than other {0} moves.
LMoveEvoFLower = Incompatible evolution moves. {0} Move learned at a lower level than other {1} moves.
LMoveFDefault_0 = Default move in Generation {0}.
LMoveFExpect_0 = Expected the following Moves: {0}
LMoveFExpectSingle_0 = Expected: {0}
LMoveFLevelUp_0 = Learned by Level-up in Generation {0}.
LMoveFTMHM_0 = Learned by TM/HM in Generation {0}.
LMoveFTutor_0 = Learned by Move Tutor in Generation {0}.
LMoveKeldeoMismatch = Keldeo Move/Form mismatch.
LMoveNincada = Only one Ninjask move allowed.
LMoveNincadaEvo = Learned by evolving Nincada into Ninjask.
LMoveNincadaEvoF_0 = Learned by evolving Nincada into Ninjask in Generation {0}.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = Move {0} PP is above the amount allowed.
LMovePPUpsTooHigh_0 = Move {0} PP Ups is above the amount allowed.
LMoveRelearnDexNav = Not an expected DexNav move.
LMoveRelearnEgg = Base Egg move.
LMoveRelearnEggMissing = Base Egg move missing.
LMoveRelearnFExpect_0 = Expected the following Relearn Moves: {0} ({1})
LMoveRelearnFMiss_0 = Relearn Moves missing: {0}
LMoveRelearnInvalid = Not an expected Relearnable move.
LMoveRelearnNone = Expected no Relearn Move in slot.
LMoveRelearnUnderground = Not an expected Underground egg move.
LMoveShopAlphaMoveShouldBeMastered = Alpha Move should be marked as mastered.
LMoveShopAlphaMoveShouldBeOther = Alpha encounter cannot be found with this Alpha Move.
LMoveShopAlphaMoveShouldBeZero = Only Alphas may have an Alpha Move set.
LMoveShopMasterInvalid_0 = Cannot manually master {0}: not permitted to master.
LMoveShopMasterNotLearned_0 = Cannot manually master {0}: not in possible learned level up moves.
LMoveShopPurchaseInvalid_0 = Cannot purchase {0} from the move shop.
LMoveSourceDefault = Default move.
LMoveSourceDuplicate = Duplicate Move.
LMoveSourceEgg = Egg Move.
LMoveSourceEggEvent = Event Egg Move.
LMoveSourceEmpty = Empty Move.
LMoveSourceInvalid = Invalid Move.
LMoveSourceInvalidSketch = Invalid Move (Sketch).
LMoveSourceLevelUp = Learned by Level-up.
LMoveSourceRelearn = Relearnable Move.
LMoveSourceShared = Shared Non-Relearn Move.
LMoveSourceSharedF = Shared Non-Relearn Move in Generation {0}.
LMoveSourceSpecial = Special Non-Relearn Move.
LMoveSourceTMHM = Learned by TM/HM.
LMoveSourceTR = Unexpected Technical Record Learned flag: {0}
LMoveSourceTutor = Learned by Move Tutor.
LNickFlagEggNo = Egg must be not nicknamed.
LNickFlagEggYes = Egg must be nicknamed.
LNickInvalidChar = Cannot be given this Nickname.
LNickLengthLong = Nickname too long.
LNickLengthShort = Nickname is empty.
LNickMatchLanguage = Nickname matches species name.
LNickMatchLanguageEgg = Egg matches language Egg name.
LNickMatchLanguageEggFail = Egg name does not match language Egg name.
LNickMatchLanguageFail = Nickname does not match species name.
LNickMatchLanguageFlag = Nickname flagged, matches species name.
LNickMatchNoOthers = Nickname does not match another species name.
LNickMatchNoOthersFail = Nickname matches another species name (+language).
LOT_IDEqual = TID16 and SID16 are equal.
LOT_IDInvalid = TID and SID combination is not possible.
LOT_IDs0 = TID16 and SID16 are 0.
LOT_SID0 = SID16 is zero.
LOT_SID0Invalid = SID16 should be 0.
LOT_TID0 = TID16 is zero.
LOTLanguage = Language ID should be {0}, not {1}.
LOTLong = OT Name too long.
LOTShort = OT Name too short.
LOTSuspicious = Suspicious Original Trainer details.
LPIDEncryptWurmple = Wurmple evolution Encryption Constant mismatch.
LPIDEncryptZero = Encryption Constant is not set.
LPIDEqualsEC = Encryption Constant matches PID.
LPIDGenderMatch = Gender matches PID.
LPIDGenderMismatch = PID-Gender mismatch.
LPIDNatureMatch = Nature matches PID.
LPIDNatureMismatch = PID-Nature mismatch.
LPIDTypeMismatch = PID+ correlation does not match what was expected for the Encounter's type.
LPIDZero = PID is not set.
LPokerusDaysTooHigh_0 = Pokérus Days Remaining value is too high; expected <= {0}.
LPokerusStrainUnobtainable_0 = Pokérus Strain {0} cannot be obtained.
LRibbonAllValid = All ribbons accounted for.
LRibbonEgg = Can't receive Ribbon(s) as an Egg.
LRibbonFInvalid_0 = Invalid Ribbons:
LRibbonFMissing_0 = Missing Ribbons:
LRibbonMarkingAffixedF_0 = Invalid Affixed Ribbon/Marking: {0}
LRibbonMarkingFInvalid_0 = Invalid Marking: {0}
LStatAlphaInvalid = Alpha Flag mismatch.
LStatBattleVersionInvalid = Battle Version is not within the expected range.
LStatDynamaxInvalid = Dynamax Level is not within the expected range.
LStatGigantamaxInvalid = Gigantamax Flag mismatch.
LStatGigantamaxValid = Gigantamax Flag was changed via Max Soup.
LStatIncorrectCP = Calculated CP does not match stored value.
LStatIncorrectHeight = Calculated Height does not match stored value.
LStatIncorrectHeightCopy = Copy Height does not match the original value.
LStatIncorrectHeightValue = Height does not match the expected value.
LStatIncorrectWeight = Calculated Weight does not match stored value.
LStatIncorrectWeightValue = Weight does not match the expected value.
LStatInvalidHeightWeight = Height / Weight values are statistically improbable.
LStatNatureInvalid = Stat Nature is not within the expected range.
LStatNobleInvalid = Noble Flag mismatch.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = Super Training complete flag mismatch.
LSuperDistro = Distribution Super Training missions are not released.
LSuperEgg = Can't Super Train an Egg.
LSuperNoComplete = Can't have active Super Training complete flag for origins.
LSuperNoUnlocked = Can't have active Super Training unlocked flag for origins.
LSuperUnavailable = Super Training missions are not available in games visited.
LSuperUnused = Unused Super Training Flag is flagged.
LTeraTypeIncorrect = Tera Type does not match the expected value.
LTeraTypeMismatch = Tera Type does not match either of the default types.
LTradeNotAvailable = Encounter cannot be traded to the active trainer.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = Can't obtain Species from Virtual Console games.
LTransferCurrentHandlerInvalid = Invalid Current handler value, trainer details for save file expected another value.
LTransferEgg = Can't transfer Eggs between Generations.
LTransferEggLocationTransporter = Invalid Met Location, expected Poké Transfer.
LTransferEggMetLevel = Invalid Met Level for transfer.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Flagged as illegal by the game (glitch abuse).
LTransferHTFlagRequired = Current handler cannot be the OT.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = Handling trainer does not match the expected trainer language.
LTransferHTMismatchName = Handling trainer does not match the expected trainer name.
LTransferMet = Invalid Met Location, expected Poké Transfer or Crown.
LTransferMetLocation = Invalid Transfer Met Location.
LTransferMove = Incompatible transfer move.
LTransferMoveG4HM = Defog and Whirlpool. One of the two moves should have been removed before transferred to Generation 5.
LTransferMoveHM = Generation {0} HM. Should have been removed before transferred to Generation {1}.
LTransferNature = Invalid Nature for transfer Experience.
LTransferNotPossible = Unable to transfer into current format from origin format.
LTransferObedienceLevel = Invalid Obedience Level.
LTransferOriginFInvalid0_1 = {0} origin cannot exist in the currently loaded ({1}) save file.
LTransferPIDECBitFlip = PID should be equal to EC [with top bit flipped]!
LTransferPIDECEquals = PID should be equal to EC!
LTransferPIDECXor = Encryption Constant matches shinyxored PID.
LTransferTrackerMissing = Pokémon HOME Transfer Tracker is missing.
LTransferTrackerShouldBeZero = Pokémon HOME Transfer Tracker should be 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = Internal error.
L_ALegal = Legal!
L_AnalysisUnavailable = Analysis not available for this Pokémon.
L_AValid = Valid.
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} Move {1}: {2}
L_F0_RM_1_2 = {0} Relearn Move {1}: {2}
L_FEncounterType_0 = Encounter Type: {0}
L_FOriginSeed_0 = Origin Seed: {0}
L_FPIDType_0 = PID Type: {0}
L_SFishy = Fishy
L_SInvalid = Invalid
L_SNotImplemented = Not Implemented
L_SValid = Valid
L_XEnigmaBerry_0 = {0} BERRY
L_XHT = HT
L_XKorean = Korean
L_XKoreanNon = Non-Korean
L_XLocation = Location
L_XMatches0_1 = Matches: {0} {1}
L_XNickname = Nickname
L_XOT = OT
L_XRareFormEvo_0_1 = Evolves into form: {0} (rare: {1})
L_XWurmpleEvo_0 = Wurmple Evolution: {0}
LAbilityCapsuleUsed = Ability available with Ability Capsule.
LAbilityFlag = Ability matches ability number.
LAbilityHiddenFail = Hidden Ability mismatch for encounter type.
LAbilityHiddenUnavailable = Hidden Ability not available.
LAbilityMismatch = Ability mismatch for encounter.
LAbilityMismatch3 = Ability does not match Generation 3 species ability.
LAbilityMismatchFlag = Ability does not match ability number.
LAbilityMismatchGift = Ability does not match Mystery Gift.
LAbilityMismatchGrotto = Hidden Grotto captures should have Hidden Ability.
LAbilityMismatchHordeSafari = Hidden Ability on non-horde/friend safari wild encounter.
LAbilityMismatchPID = Ability does not match PID.
LAbilityMismatchSOS = Hidden Ability on non-SOS wild encounter.
LAbilityPatchRevertUsed = Ability available with Ability Patch Revert.
LAbilityPatchUsed = Ability available with Ability Patch.
LAbilityUnexpected = Ability is not valid for species/form.
LAwakenedCap = Individual AV cannot be greater than {0}.
LAwakenedShouldBeValue = Individual ({1}) AV should be greater than {0}.
LBallAbility = Can't obtain Hidden Ability with Ball.
LBallEggCherish = Can't have Cherish Ball for regular Egg.
LBallEggMaster = Can't have Master Ball for regular Egg.
LBallEnc = Correct ball for encounter type.
LBallEncMismatch = Can't have ball for encounter type.
LBallHeavy = Can't have Heavy Ball for light, low-catch rate species (Gen VII).
LBallNone = No check satisfied, assuming illegal.
LBallSpecies = Can't obtain species in Ball.
LBallSpeciesPass = Ball possible for species.
LBallUnavailable = Ball unobtainable in origin Generation.
LContestSheenTooHigh_0 = Contest Stat Sheen should be <= {0}.
LContestSheenTooLow_0 = Contest Stat Sheen should be >= {0}.
LContestZero = Contest Stats should be 0.
LContestZeroSheen = Contest Stat Sheen should be 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = Met Date is outside of distribution window.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 2 EVs remaining.
LEffortAbove252 = EVs cannot go above 252.
LEffortAbove510 = EV total cannot be above 510.
LEffortAllEqual = EVs are all equal.
LEffortCap100 = Individual EV for a level 100 encounter in Generation 4 cannot be greater than 100.
LEffortEgg = Eggs cannot receive EVs.
LEffortEXPIncreased = All EVs are zero, but leveled above Met Level.
LEffortShouldBeZero = Cannot receive EVs.
LEffortUntrainedCap = Individual EV without changing EXP cannot be greater than {0}.
LEggContest = Cannot increase Contest Stats of an Egg.
LEggEXP = Eggs cannot receive experience.
LEggFMetLevel_0 = Invalid Met Level, expected {0}.
LEggHatchCycles = Invalid Egg hatch cycles.
LEggLocation = Able to hatch an Egg at Met Location.
LEggLocationInvalid = Can't hatch an Egg at Met Location.
LEggLocationNone = Invalid Egg Location, expected none.
LEggLocationPalPark = Invalid Met Location, expected Pal Park.
LEggLocationTrade = Able to hatch a traded Egg at Met Location.
LEggLocationTradeFail = Invalid Egg Location, shouldn't be 'traded' while an Egg.
LEggMetLocationFail = Can't obtain Egg from Egg Location.
LEggNature = Eggs cannot have their Stat Nature changed.
LEggPokeathlon = Eggs cannot have Pokéathlon stats.
LEggPokerus = Eggs cannot be infected with Pokérus.
LEggPP = Eggs cannot have modified move PP counts.
LEggPPUp = Cannot apply PP Ups to an Egg.
LEggRelearnFlags = Expected no Relearn Move Flags.
LEggShinyLeaf = Eggs cannot have Shiny Leaf/Crown.
LEggShinyPokeStar = Eggs cannot be a Pokéstar Studios star.
LEggSpecies = Can't obtain Egg for this species.
LEggUnhatched = Valid un-hatched Egg.
LEncCondition = Valid Wild Encounter at location.
LEncConditionBadRNGFrame = Unable to match encounter conditions to a possible RNG frame.
LEncConditionBadSpecies = Species does not exist in origin game.
LEncConditionBlack = Valid Wild Encounter at location (Black Flute).
LEncConditionBlackLead = Valid Wild Encounter at location (Black Flute & Pressure/Hustle/Vital Spirit).
LEncConditionDexNav = Valid Wild Encounter at location (DexNav).
LEncConditionLead = Valid Wild Encounter at location (Pressure/Hustle/Vital Spirit).
LEncConditionWhite = Valid Wild Encounter at location (White Flute).
LEncConditionWhiteLead = Valid Wild Encounter at location (White Flute & Pressure/Hustle/Vital Spirit).
LEncGift = Unable to match a gift Egg encounter from origin game.
LEncGiftEggEvent = Unable to match an event Egg encounter from origin game.
LEncGiftIVMismatch = IVs do not match Mystery Gift Data.
LEncGiftNicknamed = Event gift has been nicknamed.
LEncGiftNotFound = Unable to match to a Mystery Gift in the database.
LEncGiftPIDMismatch = Mystery Gift fixed PID mismatch.
LEncGiftShinyMismatch = Mystery Gift shiny mismatch.
LEncGiftVersionNotDistributed = Mystery Gift cannot be received by this version.
LEncInvalid = Unable to match an encounter from origin game.
LEncMasteryInitial = Initial move mastery flags do not match the encounter's expected state.
LEncStaticMatch = Valid gift/static encounter.
LEncStaticPIDShiny = Static Encounter shiny mismatch.
LEncStaticRelearn = Static encounter relearn move mismatch.
LEncTradeChangedNickname = In-game Trade Nickname has been altered.
LEncTradeChangedOT = In-game Trade OT has been altered.
LEncTradeIndexBad = In-game Trade invalid index?
LEncTradeMatch = Valid in-game trade.
LEncTradeUnchanged = In-game Trade OT and Nickname have not been altered.
LEncTypeMatch = Encounter Type matches encounter.
LEncTypeMismatch = Encounter Type does not match encounter.
LEncUnreleased = Unreleased event.
LEncUnreleasedEMewJP = Non Japanese Mew from Faraway Island. Unreleased event.
LEncUnreleasedHoOArceus = Arceus from Hall of Origin. Unreleased event.
LEncUnreleasedPtDarkrai = Non Platinum Darkrai from Newmoon Island. Unreleased event.
LEncUnreleasedPtShaymin = Non Platinum Shaymin from Flower Paradise. Unreleased event.
LEReaderAmerica = American E-Reader Berry in Japanese save file.
LEReaderInvalid = Invalid E-Reader Berry.
LEReaderJapan = Japanese E-Reader Berry in international save file.
LEvoInvalid = Evolution not valid (or level/trade evolution unsatisfied).
LEvoTradeReq = In-game trade {0} should have evolved into {1}.
LEvoTradeReqOutsider = Outsider {0} should have evolved into {1}.
LEvoTradeRequired = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.
LFateful = Special in-game Fateful Encounter.
LFatefulGiftMissing = Fateful Encounter with no matching Encounter. Has the Mystery Gift data been contributed?
LFatefulInvalid = Fateful Encounter should not be checked.
LFatefulMissing = Special in-game Fateful Encounter flag missing.
LFatefulMystery = Mystery Gift Fateful Encounter.
LFatefulMysteryMissing = Mystery Gift Fateful Encounter flag missing.
LFavoriteMarkingUnavailable = Favorite Marking is not available.
LFormArgumentHigh = Form argument is too high for current form.
LFormArgumentInvalid = Form argument is not valid.
LFormArgumentLow = Form argument is too low for current form.
LFormArgumentNotAllowed = Form argument is not allowed for this encounter.
LFormArgumentValid = Form argument is valid.
LFormBattle = Form cannot exist outside of a battle.
LFormEternal = Valid Eternal Flower encounter.
LFormEternalInvalid = Invalid Eternal Flower encounter.
LFormInvalidExpect_0 = Form is invalid, expected form index {0}.
LFormInvalidGame = Form cannot be obtained in origin game.
LFormInvalidNature = Form cannot have this nature.
LFormInvalidRange = Form Count is out of range. Expected <= {0}, got {1}.
LFormItem = Held item matches Form.
LFormItemInvalid = Held item does not match Form.
LFormParty = Form cannot exist outside of Party.
LFormPikachuCosplay = Only Cosplay Pikachu can have this form.
LFormPikachuCosplayInvalid = Cosplay Pikachu cannot have the default form.
LFormPikachuEventInvalid = Event Pikachu cannot have the default form.
LFormValid = Form is Valid.
LFormVivillon = Valid Vivillon pattern.
LFormVivillonEventPre = Event Vivillon pattern on pre-evolution.
LFormVivillonInvalid = Invalid Vivillon pattern.
LFormVivillonNonNative = Non-native Vivillon pattern.
LG1CatchRateChain = Catch rate does not match any species from Pokémon evolution chain.
LG1CatchRateEvo = Catch rate match species without encounters. Expected a preevolution catch rate.
LG1CatchRateItem = Catch rate does not match a valid held item from Generation 2.
LG1CatchRateMatchPrevious = Catch Rate matches a species from Pokémon evolution chain.
LG1CatchRateMatchTradeback = Catch rate matches a valid held item from Generation 2.
LG1CatchRateNone = Catch rate does not match any species from Pokémon evolution chain or any Generation 2 held items.
LG1CharNick = Nickname from Generation 1/2 uses unavailable characters.
LG1CharOT = OT from Generation 1/2 uses unavailable characters.
LG1GBEncounter = Can't obtain Special encounter in Virtual Console games.
LG1MoveExclusive = Generation 1 exclusive move. Incompatible with Non-tradeback moves.
LG1MoveLearnSameLevel = Incompatible moves. Learned at the same level in Red/Blue and Yellow.
LG1MoveTradeback = Non-tradeback Egg move. Incompatible with Generation 1 exclusive moves.
LG1OTEvent = Incorrect RBY event OT Name.
LG1OTGender = Female OT from Generation 1/2 is invalid.
LG1Stadium = Incorrect Stadium OT.
LG1StadiumInternational = Valid International Stadium OT.
LG1StadiumJapanese = Valid Japanese Stadium OT.
LG1TradebackPreEvoMove = Non-tradeback pre evolution move. Incompatible with Generation 1 exclusive moves.
LG1Type1Fail = Invalid Type A, does not match species type.
LG1Type2Fail = Invalid Type B, does not match species type.
LG1TypeMatch1 = Valid Type A, matches species type.
LG1TypeMatch2 = Valid Type B, matches species type.
LG1TypeMatchPorygon = Porygon with valid Type A and B values.
LG1TypePorygonFail = Porygon with invalid Type A and B values. Does not a match a valid type combination.
LG1TypePorygonFail1 = Porygon with invalid Type A value.
LG1TypePorygonFail2 = Porygon with invalid Type B value.
LG2InvalidTilePark = National Park fishing encounter. Unreachable Water tiles.
LG2InvalidTileR14 = Kanto Route 14 fishing encounter. Unreachable Water tiles.
LG2InvalidTileSafari = Generation 2 Safari Zone fishing encounter. Unreachable zone.
LG2InvalidTileTreeID = Found an unreachable tree for Crystal headbutt encounter that matches OTID.
LG2InvalidTileTreeNotFound = Could not find a tree for Crystal headbutt encounter that matches OTID.
LG2OTGender = OT from Virtual Console games other than Crystal cannot be female.
LG2TreeID = Found a tree for Crystal headbutt encounter that matches OTID.
LG3EReader = Non Japanese Shadow E-reader Pokémon. Unreleased encounter.
LG3OTGender = OT from Colosseum/XD cannot be female.
LG4InvalidTileR45Surf = Johto Route 45 surfing encounter. Unreachable Water tiles.
LG5ID_N = The Name/TID16/SID16 of N is incorrect.
LG5IVAll30 = All IVs of N's Pokémon should be 30.
LG5OTGenderN = N's Pokémon must have a male OT gender.
LG5PIDShinyGrotto = Hidden Grotto captures cannot be shiny.
LG5PIDShinyN = N's Pokémon cannot be shiny.
LG5SparkleInvalid = Special in-game N's Sparkle flag should not be checked.
LG5SparkleRequired = Special in-game N's Sparkle flag missing.
LGanbaruStatTooHigh = One or more Ganbaru Value is above the natural limit of (10 - IV bonus).
LGenderInvalidNone = Genderless Pokémon should not have a gender.
LGeoBadOrder = GeoLocation Memory: Gap/Blank present.
LGeoHardwareInvalid = Geolocation: Country is not in 3DS region.
LGeoHardwareRange = Invalid Console Region.
LGeoHardwareValid = Geolocation: Country is in 3DS region.
LGeoMemoryMissing = GeoLocation Memory: Memories should be present.
LGeoNoCountryHT = GeoLocation Memory: HT Name present but has no previous Country.
LGeoNoRegion = GeoLocation Memory: Region without Country.
LHyperPerfectAll = Can't Hyper Train a Pokémon with perfect IVs.
LHyperPerfectOne = Can't Hyper Train a perfect IV.
LHyperPerfectUnavailable = Can't Hyper Train any IV(s).
LHyperTooLow_0 = Can't Hyper Train a Pokémon that isn't level {0}.
LItemEgg = Eggs cannot hold items.
LItemUnreleased = Held item is unreleased.
LIVAllEqual_0 = All IVs are {0}.
LIVF_COUNT0_31 = Should have at least {0} IVs = 31.
LIVNotCorrect = IVs do not match encounter requirements.
LLevelEXPThreshold = Current experience matches level threshold.
LLevelEXPTooHigh = Current experience exceeds maximum amount for level 100.
LLevelMetBelow = Current level is below met level.
LLevelMetGift = Met Level does not match Mystery Gift level.
LLevelMetGiftFail = Current Level below Mystery Gift level.
LLevelMetSane = Current level is not below met level.
LMarkValueOutOfRange_0 = Individual marking at index {0} is not within the allowed value range.
LMarkValueShouldBeZero = Marking flags cannot be set.
LMarkValueUnusedBitsPresent = Marking flags uses bits beyond the accessible range.
LMemoryArgBadCatch = {0} Memory: {0} did not catch this.
LMemoryArgBadHatch = {0} Memory: {0} did not hatch this.
LMemoryArgBadHT = Memory: Can't have Handling Trainer Memory as Egg.
LMemoryArgBadID = {0} Memory: Can't obtain Memory on {0} Version.
LMemoryArgBadItem = {0} Memory: Species can't hold this item.
LMemoryArgBadLocation = {0} Memory: Can't obtain Location on {0} Version.
LMemoryArgBadMove = {0} Memory: Species can't learn this move.
LMemoryArgBadOTEgg = {0} Memory: Link Trade is not a valid first memory.
LMemoryArgBadSpecies = {0} Memory: Can't capture species in game.
LMemoryArgSpecies = {0} Memory: Species can be captured in game.
LMemoryCleared = Memory: Not cleared properly.
LMemoryF_0_Valid = {0} Memory is valid.
LMemoryFeelInvalid = {0} Memory: Invalid Feeling.
LMemoryHTFlagInvalid = Untraded: Current handler should not be the Handling Trainer.
LMemoryHTGender = HT Gender invalid: {0}
LMemoryHTLanguage = HT Language is missing.
LMemoryIndexArgHT = Should have a HT Memory TextVar value (somewhere).
LMemoryIndexFeel = {0} Memory: Feeling should be index {1}.
LMemoryIndexFeelHT09 = Should have a HT Memory Feeling value 0-9.
LMemoryIndexID = {0} Memory: Should be index {1}.
LMemoryIndexIntensity = {0} Memory: Intensity should be index {1}.
LMemoryIndexIntensityHT1 = Should have a HT Memory Intensity value (1st).
LMemoryIndexIntensityMin = {0} Memory: Intensity should be at least {1}.
LMemoryIndexLinkHT = Should have a Link Trade HT Memory.
LMemoryIndexVar = {0} Memory: TextVar should be index {1}.
LMemoryMissingHT = Memory: Handling Trainer Memory missing.
LMemoryMissingOT = Memory: Original Trainer Memory missing.
LMemorySocialTooHigh_0 = Social Stat should be <= {0}
LMemorySocialZero = Social Stat should be zero.
LMemoryStatAffectionHT0 = Untraded: Handling Trainer Affection should be 0.
LMemoryStatAffectionOT0 = OT Affection should be 0.
LMemoryStatEnjoyment = Enjoyment should be {0}.
LMemoryStatFriendshipHT0 = Untraded: Handling Trainer Friendship should be 0.
LMemoryStatFriendshipOTBaseEvent = Event OT Friendship does not match base friendship.
LMemoryStatFullness = Fullness should be {0}.
LMetDetailTimeOfDay = Met Time of Day value is not within the expected range.
LMoveEggFIncompatible0_1 = {0} Inherited Move. Incompatible with {1} inherited moves.
LMoveEggIncompatible = Egg Move. Incompatible with event Egg moves.
LMoveEggIncompatibleEvent = Event Egg Move. Incompatible with normal Egg moves.
LMoveEggInherited = Inherited Egg move.
LMoveEggInheritedTutor = Inherited tutor move.
LMoveEggInvalid = Not an expected Egg move.
LMoveEggInvalidEvent = Egg Move. Not expected in an event Egg.
LMoveEggInvalidEventLevelUp = Inherited move learned by Level-up. Not expected in an event Egg.
LMoveEggInvalidEventLevelUpGift = Inherited move learned by Level-up. Not expected in a gift Egg.
LMoveEggInvalidEventTMHM = Inherited TM/HM move. Not expected in an event Egg.
LMoveEggInvalidEventTutor = Inherited tutor move. Not expected in an event Egg.
LMoveEggLevelUp = Inherited move learned by Level-up.
LMoveEggMissing = Event Egg move missing.
LMoveEggMoveGift = Egg Move. Not expected in a gift Egg.
LMoveEggTMHM = Inherited TM/HM move.
LMoveEventEggLevelUp = Inherited move learned by Level-up. Incompatible with event Egg moves.
LMoveEvoFCombination_0 = Moves combinations is not compatible with {0} evolution.
LMoveEvoFHigher = Incompatible evolution moves. {1} Move learned at a higher level than other {0} moves.
LMoveEvoFLower = Incompatible evolution moves. {0} Move learned at a lower level than other {1} moves.
LMoveFDefault_0 = Default move in Generation {0}.
LMoveFExpect_0 = Expected the following Moves: {0}
LMoveFExpectSingle_0 = Expected: {0}
LMoveFLevelUp_0 = Learned by Level-up in Generation {0}.
LMoveFTMHM_0 = Learned by TM/HM in Generation {0}.
LMoveFTutor_0 = Learned by Move Tutor in Generation {0}.
LMoveKeldeoMismatch = Keldeo Move/Form mismatch.
LMoveNincada = Only one Ninjask move allowed.
LMoveNincadaEvo = Learned by evolving Nincada into Ninjask.
LMoveNincadaEvoF_0 = Learned by evolving Nincada into Ninjask in Generation {0}.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = Move {0} PP is above the amount allowed.
LMovePPUpsTooHigh_0 = Move {0} PP Ups is above the amount allowed.
LMoveRelearnDexNav = Not an expected DexNav move.
LMoveRelearnEgg = Base Egg move.
LMoveRelearnEggMissing = Base Egg move missing.
LMoveRelearnFExpect_0 = Expected the following Relearn Moves: {0} ({1})
LMoveRelearnFMiss_0 = Relearn Moves missing: {0}
LMoveRelearnInvalid = Not an expected Relearnable move.
LMoveRelearnNone = Expected no Relearn Move in slot.
LMoveRelearnUnderground = Not an expected Underground egg move.
LMoveShopAlphaMoveShouldBeMastered = Alpha Move should be marked as mastered.
LMoveShopAlphaMoveShouldBeOther = Alpha encounter cannot be found with this Alpha Move.
LMoveShopAlphaMoveShouldBeZero = Only Alphas may have an Alpha Move set.
LMoveShopMasterInvalid_0 = Cannot manually master {0}: not permitted to master.
LMoveShopMasterNotLearned_0 = Cannot manually master {0}: not in possible learned level up moves.
LMoveShopPurchaseInvalid_0 = Cannot purchase {0} from the move shop.
LMoveSourceDefault = Default move.
LMoveSourceDuplicate = Duplicate Move.
LMoveSourceEgg = Egg Move.
LMoveSourceEggEvent = Event Egg Move.
LMoveSourceEmpty = Empty Move.
LMoveSourceInvalid = Invalid Move.
LMoveSourceInvalidSketch = Invalid Move (Sketch).
LMoveSourceLevelUp = Learned by Level-up.
LMoveSourceRelearn = Relearnable Move.
LMoveSourceShared = Shared Non-Relearn Move.
LMoveSourceSharedF = Shared Non-Relearn Move in Generation {0}.
LMoveSourceSpecial = Special Non-Relearn Move.
LMoveSourceTMHM = Learned by TM/HM.
LMoveSourceTR = Unexpected Technical Record Learned flag: {0}
LMoveSourceTutor = Learned by Move Tutor.
LNickFlagEggNo = Egg must be not nicknamed.
LNickFlagEggYes = Egg must be nicknamed.
LNickInvalidChar = Cannot be given this Nickname.
LNickLengthLong = Nickname too long.
LNickLengthShort = Nickname is empty.
LNickMatchLanguage = Nickname matches species name.
LNickMatchLanguageEgg = Egg matches language Egg name.
LNickMatchLanguageEggFail = Egg name does not match language Egg name.
LNickMatchLanguageFail = Nickname does not match species name.
LNickMatchLanguageFlag = Nickname flagged, matches species name.
LNickMatchNoOthers = Nickname does not match another species name.
LNickMatchNoOthersFail = Nickname matches another species name (+language).
LOT_IDEqual = TID16 and SID16 are equal.
LOT_IDInvalid = TID and SID combination is not possible.
LOT_IDs0 = TID16 and SID16 are 0.
LOT_SID0 = SID16 is zero.
LOT_SID0Invalid = SID16 should be 0.
LOT_TID0 = TID16 is zero.
LOTLanguage = Language ID should be {0}, not {1}.
LOTLong = OT Name too long.
LOTShort = OT Name too short.
LOTSuspicious = Suspicious Original Trainer details.
LPIDEncryptWurmple = Wurmple evolution Encryption Constant mismatch.
LPIDEncryptZero = Encryption Constant is not set.
LPIDEqualsEC = Encryption Constant matches PID.
LPIDGenderMatch = Gender matches PID.
LPIDGenderMismatch = PID-Gender mismatch.
LPIDNatureMatch = Nature matches PID.
LPIDNatureMismatch = PID-Nature mismatch.
LPIDTypeMismatch = PID+ correlation does not match what was expected for the Encounter's type.
LPIDZero = PID is not set.
LPokerusDaysTooHigh_0 = Pokérus Days Remaining value is too high; expected <= {0}.
LPokerusStrainUnobtainable_0 = Pokérus Strain {0} cannot be obtained.
LRibbonAllValid = All ribbons accounted for.
LRibbonEgg = Can't receive Ribbon(s) as an Egg.
LRibbonFInvalid_0 = Invalid Ribbons:
LRibbonFMissing_0 = Missing Ribbons:
LRibbonMarkingAffixedF_0 = Invalid Affixed Ribbon/Marking: {0}
LRibbonMarkingFInvalid_0 = Invalid Marking: {0}
LStatAlphaInvalid = Alpha Flag mismatch.
LStatBattleVersionInvalid = Battle Version is not within the expected range.
LStatDynamaxInvalid = Dynamax Level is not within the expected range.
LStatGigantamaxInvalid = Gigantamax Flag mismatch.
LStatGigantamaxValid = Gigantamax Flag was changed via Max Soup.
LStatIncorrectCP = Calculated CP does not match stored value.
LStatIncorrectHeight = Calculated Height does not match stored value.
LStatIncorrectHeightCopy = Copy Height does not match the original value.
LStatIncorrectHeightValue = Height does not match the expected value.
LStatIncorrectWeight = Calculated Weight does not match stored value.
LStatIncorrectWeightValue = Weight does not match the expected value.
LStatInvalidHeightWeight = Height / Weight values are statistically improbable.
LStatNatureInvalid = Stat Nature is not within the expected range.
LStatNobleInvalid = Noble Flag mismatch.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = Super Training complete flag mismatch.
LSuperDistro = Distribution Super Training missions are not released.
LSuperEgg = Can't Super Train an Egg.
LSuperNoComplete = Can't have active Super Training complete flag for origins.
LSuperNoUnlocked = Can't have active Super Training unlocked flag for origins.
LSuperUnavailable = Super Training missions are not available in games visited.
LSuperUnused = Unused Super Training Flag is flagged.
LTeraTypeIncorrect = Tera Type does not match the expected value.
LTeraTypeMismatch = Tera Type does not match either of the default types.
LTradeNotAvailable = Encounter cannot be traded to the active trainer.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = Incorrectly transferred from previous generation.
LTransferCurrentHandlerInvalid = Invalid Current handler value, trainer details for save file expected another value.
LTransferEgg = Can't transfer Eggs between Generations.
LTransferEggLocationTransporter = Invalid Met Location, expected Poké Transfer.
LTransferEggMetLevel = Invalid Met Level for transfer.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Flagged as illegal by the game (glitch abuse).
LTransferHTFlagRequired = Current handler cannot be the OT.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = Handling trainer does not match the expected trainer language.
LTransferHTMismatchName = Handling trainer does not match the expected trainer name.
LTransferMet = Invalid Met Location, expected Poké Transfer or Crown.
LTransferMetLocation = Invalid Transfer Met Location.
LTransferMove = Incompatible transfer move.
LTransferMoveG4HM = Defog and Whirlpool. One of the two moves should have been removed before transferred to Generation 5.
LTransferMoveHM = Generation {0} HM. Should have been removed before transferred to Generation {1}.
LTransferNature = Invalid Nature for transfer Experience.
LTransferNotPossible = Unable to transfer into current format from origin format.
LTransferObedienceLevel = Invalid Obedience Level.
LTransferOriginFInvalid0_1 = {0} origin cannot exist in the currently loaded ({1}) save file.
LTransferPIDECBitFlip = PID should be equal to EC [with top bit flipped]!
LTransferPIDECEquals = PID should be equal to EC!
LTransferPIDECXor = Encryption Constant matches shinyxored PID.
LTransferTrackerMissing = Pokémon HOME Transfer Tracker is missing.
LTransferTrackerShouldBeZero = Pokémon HOME Transfer Tracker should be 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = Error interno.
L_ALegal = ¡Legal!
L_AnalysisUnavailable = Análisis no disponible para éste Pokémon.
L_AValid = Válido.
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} Movimiento {1}: {2}
L_F0_RM_1_2 = {0} Movimientos recordable {1}: {2}
L_FEncounterType_0 = Tipo de Encuentro: {0}
L_FOriginSeed_0 = Semilla original: {0}
L_FPIDType_0 = Tipo de PID: {0}
L_SFishy = Sospechoso
L_SInvalid = Inválido
L_SNotImplemented = No implementado
L_SValid = Válido
L_XEnigmaBerry_0 = BAYA {0}
L_XHT = EE
L_XKorean = Coreano
L_XKoreanNon = No es coreano.
L_XLocation = Location
L_XMatches0_1 = Coinciden: {0} {1}
L_XNickname = Nickname
L_XOT = EO
L_XRareFormEvo_0_1 = Evolves into form: {0} (rare: {1})
L_XWurmpleEvo_0 = Evolución de Wurmple: {0}
LAbilityCapsuleUsed = Habilidad disponible con una Cápsula Habilidad.
LAbilityFlag = La habilidad coincide con el número de habilidad.
LAbilityHiddenFail = La habilidad oculta no es correcta para el tipo de encuentro.
LAbilityHiddenUnavailable = Habilidad oculta no disponible.
LAbilityMismatch = La habilidad no es correcta para el encuentro.
LAbilityMismatch3 = La habilidad no coincide con la habilidad de la especie en la 3ra generación.
LAbilityMismatchFlag = La habilidad no coincide con el número de habilidad.
LAbilityMismatchGift = La habilidad no coincide con la del Regalo Misterioso.
LAbilityMismatchGrotto = Las capturas en el Claro Oculto deben tener habilidad oculta.
LAbilityMismatchHordeSafari = Habilidad Oculta en un encuentro salvaje que no es mediante Hordas/Safari Amistad.
LAbilityMismatchPID = La habilidad no coincide con el PID.
LAbilityMismatchSOS = Habilidad oculta en un encuentro salvaje que no es por Llamada SOS.
LAbilityPatchRevertUsed = Habilidad disponible con Parche Habilidad a la inversa.
LAbilityPatchUsed = Habilidad disponible con Parche Habilidad.
LAbilityUnexpected = La Habilidad no es válida para esta especie/forma.
LAwakenedCap = Los AVs individuales no pueden ser mayor que: {0}.
LAwakenedShouldBeValue = Los AVs individuales deberían ser mayor que: {0} ({1}).
LBallAbility = No se puede tener habilidad oculta con esta Ball.
LBallEggCherish = No se puede tener una Gloria Ball en un Huevo común.
LBallEggMaster = No se puede tener una Master Ball en un Huevo común.
LBallEnc = Ball correcta para el tipo de encuentro.
LBallEncMismatch = Ball inobtenible para el tipo de encuentro.
LBallHeavy = No se puede tener una Peso Ball para especies ligeras, con poco ratio de captura (7ma generación).
LBallNone = No cumple con la validación, se asume ilegalidad.
LBallSpecies = La especie no se puede obtener en esta Ball.
LBallSpeciesPass = Ball posible para esta especie.
LBallUnavailable = Ball imposible en la generación de origen.
LContestSheenTooHigh_0 = La estadística de concurso Brillo debería ser <= {0}.
LContestSheenTooLow_0 = La estadística de concurso Brillo debería ser >= {0}.
LContestZero = Las estadísticas de concurso deberían ser 0.
LContestZeroSheen = La estadística de concurso Brillo debería ser 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = La fecha de encuentro está fuera del rango de fechas de distribución.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 2 EVs restantes.
LEffortAbove252 = Los EVs no pueden superar los 252.
LEffortAbove510 = Los EVs totales no pueden ser más de 510.
LEffortAllEqual = Todos los EVs son iguales.
LEffortCap100 = El valor de un EV individual para un encuentro de nivel 100 en la 4ta generación no puede ser superior 100.
LEffortEgg = Los Huevos no pueden tener EVs.
LEffortEXPIncreased = Todos los EVs son 0, pero el nivel está por encima del nivel de encuentro.
LEffortShouldBeZero = No puede recibir EVs.
LEffortUntrainedCap = El valor del EV sin modificar la experiencia no puede ser superior a {0}.
LEggContest = No se pueden aumentar las estadísticas de Concurso de un Huevo.
LEggEXP = Los Huevos no pueden recibir experiencia.
LEggFMetLevel_0 = Encontrado con un nivel inválido, se esperaba {0}.
LEggHatchCycles = Ciclos de eclosión del Huevo inválidos.
LEggLocation = Se puede eclosionar el Huevo en la localización.
LEggLocationInvalid = No se puede eclosionar el Huevo en la localización.
LEggLocationNone = Localización del Huevo inválida, no se esperaba ninguna.
LEggLocationPalPark = Localización inválida, se esperaba Parque Compi.
LEggLocationTrade = Se puede eclosionar el Huevo intercambiado en la localización.
LEggLocationTradeFail = Localización del Huevo inválida, no debería haber sido intercambiado mientras era un Huevo.
LEggMetLocationFail = No se puede obtener el Huevo en la localización.
LEggNature = Los Huevos no pueden tener Naturaleza estadística.
LEggPokeathlon = Los Huevos no pueden tener estadísticas del Pokéathlon.
LEggPokerus = Los Huevos no pueden estar infectados con Pokérus.
LEggPP = Los Huevos no pueden tener los contadores de PP modificados.
LEggPPUp = No se puede aplicar Más PP a un huevo.
LEggRelearnFlags = Los Huevos no pueden tener Discos Técnicos marcados.
LEggShinyLeaf = Los Huevos no pueden tener Hoja/Corona dorada.
LEggShinyPokeStar = Los Huevos no pueden ser una estrella de los Estudios Cinematográficos Pokéwoods.
LEggSpecies = Esta especie no puede tener Huevos.
LEggUnhatched = Huevo eclosionado inválido.
LEncCondition = Encuentro salvaje válido en la localización.
LEncConditionBadRNGFrame = Imposible de encontrar las condiciones para un posible frame de RNG.
LEncConditionBadSpecies = La especie no existe en el juego de origen.
LEncConditionBlack = Encuentro salvaje válido en la localización (Flauta Negra).
LEncConditionBlackLead = Encuentro salvaje válido en la localización (Flauta Negra y Presión/Entusiasmo/Espíritu Vital).
LEncConditionDexNav = Encuentro salvaje válido en la localización (DexNav).
LEncConditionLead = Encuentro salvaje válido en la localización (Presión/Entusiasmo/Espíritu Vital).
LEncConditionWhite = Encuentro salvaje válido en la localización (Flauta Blanca).
LEncConditionWhiteLead = Encuentro salvaje válido en la localización (Flauta Blanca y Presión/Entusiasmo/Espíritu Vital).
LEncGift = Imposible encontrar un encuentro con el Huevo de Evento en el juego de origen.
LEncGiftEggEvent = Imposible encontrar un Huevo de Evento en el juego de origen.
LEncGiftIVMismatch = Los IVs no coinciden con los datos del Regalo Misterio.
LEncGiftNicknamed = El regalo de Evento tiene mote.
LEncGiftNotFound = Imposible de encontrar este Regalo Misterioso en la base de datos.
LEncGiftPIDMismatch = El PID obligatorio del Regalo Misterioso no es correcto.
LEncGiftShinyMismatch = Regalo Misterioso variocolor incorrecto.
LEncGiftVersionNotDistributed = El Regalo Misterioso no puede ser recibido en esa edición.
LEncInvalid = Imposible de encontrar un encuentro en el juego de origen.
LEncMasteryInitial = Las marcas iniciales de dominio de movimientos no coincide con las esperadas para el encuentro.
LEncStaticMatch = Encuentro estático/Regalo válido.
LEncStaticPIDShiny = El encuentro estático con el Pokémon variocolor no es correcto.
LEncStaticRelearn = El movimiento recordable del encuentro estático no es correcto.
LEncTradeChangedNickname = El mote del intercambio del juego ha sido alterado.
LEncTradeChangedOT = EL EO del intercambio del juego ha sido alterado.
LEncTradeIndexBad = ¿El índice de intercambio del juego no es válido?
LEncTradeMatch = Intercambio del juego válido.
LEncTradeUnchanged = El EO de intercambio del juego y el mote no han sido alterados.
LEncTypeMatch = El tipo de encuentro corresponde con el encuentro.
LEncTypeMismatch = El tipo de encuentro no coincide con el encuentro.
LEncUnreleased = Evento no liberado.
LEncUnreleasedEMewJP = Mew de la Isla Suprema no japonés. Evento no liberado.
LEncUnreleasedHoOArceus = Arceus de la Sala Origen. Evento no liberado.
LEncUnreleasedPtDarkrai = Darkrai de la Isla Luna Nueva no proveniente de Pokémon Platino. Evento no liberado.
LEncUnreleasedPtShaymin = Shaymin del Paraíso Floral no proveniente de Pokémon Platino. Evento no liberado.
LEReaderAmerica = Baya de E-Reader americano en un archivo japonés.
LEReaderInvalid = Baya de E-Reader inválida.
LEReaderJapan = Baya de E-Reader japonés en un archivo internacional.
LEvoInvalid = Evolución inválida (o nivel/evolución por intercambio no satisfactorios).
LEvoTradeReq = El intercambio del juego {0} debería haber evolucionado en {1}.
LEvoTradeReqOutsider = Forastero {0} debería haber evolucionado en {1}.
LEvoTradeRequired = La evolución específica de la versión requiere de un intercambio con la versión opuesta. Se requiere un entrenador anterior.
LFateful = Encuentro fatídico especial del juego.
LFatefulGiftMissing = Encuentro fatídico no coincide con el Encuentro. ¿Es un Regalo Misterioso contribuido?
LFatefulInvalid = El encuentro fatídico no debería estar marcado.
LFatefulMissing = Falta la marca de encuentro fatídico especial del juego.
LFatefulMystery = Encuentro fatídico de Regalo Misterioso.
LFatefulMysteryMissing = Falta la marca de encuentro fatídico de Regalo Misterioso.
LFavoriteMarkingUnavailable = Marca de favorito no disponible.
LFormArgumentHigh = El argumento de la forma es muy alto para la forma actual.
LFormArgumentInvalid = El argumento de la forma no es válido.
LFormArgumentLow = El argumento de la forma es muy bajo para la forma actual.
LFormArgumentNotAllowed = El argumento de la forma no está permitida para éste encuentro.
LFormArgumentValid = El argumento de la forma es válido.
LFormBattle = La forma no puede existir fuera de combate.
LFormEternal = Encuentro con Flor Eterna válido.
LFormEternalInvalid = Encuentro con Flor Eterna inválido.
LFormInvalidExpect_0 = La forma es inválida, se esperaba el índice de forma {0}.
LFormInvalidGame = La forma no se puede obtener en el juego de origen.
LFormInvalidNature = La forma no puede tener esta Naturaleza.
LFormInvalidRange = Contador de forma fuera de rango. Se esperaba <= {0}, se obtuvo {1}.
LFormItem = El objeto equipado coincide con la forma.
LFormItemInvalid = El objeto equipado no coincide con la forma.
LFormParty = La forma no puede existir fuera del equipo.
LFormPikachuCosplay = Solo Pikachu Coqueta puede tener esta forma.
LFormPikachuCosplayInvalid = Pikachu Coqueta no puede tener la forma por defecto.
LFormPikachuEventInvalid = El Pikachu de Evento no puede tener la forma por defecto.
LFormValid = Forma es válida.
LFormVivillon = Patrón de Vivillon válido.
LFormVivillonEventPre = Patrón de Vivillon de evento en una preevolución.
LFormVivillonInvalid = Patrón de Vivillon inválido.
LFormVivillonNonNative = Patrón de Vivillon no autóctono.
LG1CatchRateChain = El ratio de captura no coincide con ninguna especie de la cadena evolutiva del Pokémon.
LG1CatchRateEvo = El ratio de captura coincide con la especie pero sin encuentros. Se espera un ratio de captura de una preevolución.
LG1CatchRateItem = El ratio de captura no coincide con un objeto equipado válido de la 2da Generación.
LG1CatchRateMatchPrevious = Ratio de Captura coincide con las especies de la cadena evolutiva.
LG1CatchRateMatchTradeback = Ratio de Captura coincide con un objeto válido equipado de la 2da Generación.
LG1CatchRateNone = El ratio de captura no coincide con ninguna especie de la cadena evolutiva del Pokémon o algún objeto de la 2da Generación.
LG1CharNick = El mote de la 1ra y 2a generación usa caracteres no disponibles.
LG1CharOT = El EO de la 1ra y 2a generación usa caracteres no disponibles.
LG1GBEncounter = No se puede obtener un encuentro especial en los juegos de Consola Virtual.
LG1MoveExclusive = Movimiento exclusivo de 1ra generación. Incompatible con movimientos de regreso.
LG1MoveLearnSameLevel = Movimientos incompatibles. Aprendidos al mismo nivel en Rojo/Azul y Amarillo.
LG1MoveTradeback = Movimiento Huevo incompatible con movimientos exclusivos de Generación 1.
LG1OTEvent = Nombre del EO del Evento de Rojo/Azul/Amarillo incorrecto.
LG1OTGender = EO femenino inválido para la 1ra y 2a generación.
LG1Stadium = EO del Stadium incorrecto.
LG1StadiumInternational = EO del Stadium internacional válido.
LG1StadiumJapanese = EO del Stadium japonés válido.
LG1TradebackPreEvoMove = El movimiento de preevolución es incompatible con los exclusivos de 1ra generación.
LG1Type1Fail = Tipo A Inválido, no coincide con la especie.
LG1Type2Fail = Tipo B Inválido, no coincide con la especie.
LG1TypeMatch1 = Tipo A Válido, coincide con la especie.
LG1TypeMatch2 = Tipo B Válido, coincide con la especie.
LG1TypeMatchPorygon = Porygon con valores Tipo A y B válidos.
LG1TypePorygonFail = Porygon con valores de Tipo A y B inválidos. No coinciden con una combinación de tipo válida.
LG1TypePorygonFail1 = Porygon con un valor de Tipo A inválido.
LG1TypePorygonFail2 = Porygon con un valor de Tipo B inválido.
LG2InvalidTilePark = Encuentro mediante pesca en el Parque Nacional. Zonas de agua inalcanzables.
LG2InvalidTileR14 = Encuentro mediante pesca en la ruta 14 de Kanto. Zonas de agua inalcanzables.
LG2InvalidTileSafari = Encuentro mediante pesca en la Zona Safari de 2da Generación. Zona inalcanzable.
LG2InvalidTileTreeID = Se encontró un árbol inalcanzable para el encuentro mediante Cabezazo en Cristal que coincida con el OTID.
LG2InvalidTileTreeNotFound = No se pudo encontrar un árbol para el encuentro mediante Cabezazo en Cristal que coincida con el OTID.
LG2OTGender = Los OT de los juegos de la consola virtual que no sean Cristal no pueden ser mujeres.
LG2TreeID = Se encontró un árbol para el encuentro mediante Cabezazo en Cristal que coincide con el OTID.
LG3EReader = Pokémon oscuro de E-Reader japonés. Encuentro no liberado.
LG3OTGender = EO de Colosseum/XD no puede ser femenino.
LG4InvalidTileR45Surf = Encuentro mediante Surf en la ruta 45 de Johto. Zonas de agua inalcanzables.
LG5ID_N = El nombre/TID16/SID16 de N es incorrecto.
LG5IVAll30 = Todos los IVs de los Pokémon de N deberían ser 30.
LG5OTGenderN = Los Pokémon de N deben tener un género OT masculino.
LG5PIDShinyGrotto = Las Capturas en Los Claros Ocultos no pueden ser variocolor.
LG5PIDShinyN = Los Pokémon de N no pueden ser variocolor.
LG5SparkleInvalid = La marca chispeante especial de los Pokémon de N en el juego no debería marcarse.
LG5SparkleRequired = Falta la marca chispeante especial de los Pokémon de N en el juego.
LGanbaruStatTooHigh = Un nivel o más de esfuerzo es mayor del límite natural de (10 - bonus IV).
LGenderInvalidNone = Pokémon sn género no debería tener género.
LGeoBadOrder = Recuerdo de Geolocalización: En blanco/nulo.
LGeoHardwareInvalid = Geolocalización: El país no se encuentra en la región de la 3DS.
LGeoHardwareRange = Región de consola inválida.
LGeoHardwareValid = Geolocalización: El país está en la región de la 3DS.
LGeoMemoryMissing = Recuerdo de Geolocalización: Los recuerdos deberían estar presentes.
LGeoNoCountryHT = Recuerdo de Geolocalización: El nombre del entrenador anterior aparece pero no tiene país anterior.
LGeoNoRegion = Recuerdo de Geolocalización: Región sin país.
LHyperPerfectAll = No se puede usar el Entrenamiento Extremo con IVs perfectos.
LHyperPerfectOne = No se puede usar el Entrenamiento Extremo con un IV perfecto.
LHyperPerfectUnavailable = No se puede usar el Entrenamiento Extremo en cualquier IV.
LHyperTooLow_0 = No se puede usar el Entrenamiento Extremo en un Pokémon que no esté al nivel {0}.
LItemEgg = Los Huevos no pueden tener objetos equipados.
LItemUnreleased = El objeto equipado aún no está disponible.
LIVAllEqual_0 = Todos los IVs son {0}.
LIVF_COUNT0_31 = Debería tener al menos {0} IVs = 31.
LIVNotCorrect = Los IVs no coinciden con los requerimientos del encuentro.
LLevelEXPThreshold = La experiencia actual coincide con la del umbral de nivel.
LLevelEXPTooHigh = La experiencia actual supera el máximo para el nivel 100.
LLevelMetBelow = El nivel actual está por debajo del nivel de encuentro.
LLevelMetGift = El nivel actual no coincide con el nivel del Regalo Misterioso.
LLevelMetGiftFail = El nivel actual está por debajo del nivel del Regalo Misterioso.
LLevelMetSane = El nivel actual no está por debajo del nivel de encuentro.
LMarkValueOutOfRange_0 = La marca individual en el índice {0} no está en el rango de valores permitidos.
LMarkValueShouldBeZero = No se pueden poner las marcas.
LMarkValueUnusedBitsPresent = Las marcas usan bits más allá del rango accesible.
LMemoryArgBadCatch = {0} Recuerdo: {0} no capturó esto.
LMemoryArgBadHatch = {0} Recuerdo: {0} no eclosionó esto.
LMemoryArgBadHT = Recuerdo: No puede tener recuerdo de un entrenador anterior siendo un Huevo.
LMemoryArgBadID = {0} Recuerdo: No se puede obtener un recuerdo en la edición {0} .
LMemoryArgBadItem = {0} Recuerdo: Las especies no pueden contener este objeto.
LMemoryArgBadLocation = {0} Recuerdo: No se puede obtener la localización en la edición {0}.
LMemoryArgBadMove = {0} Recuerdo: La especie no puede aprender este movimiento.
LMemoryArgBadOTEgg = {0} Recuerdo: Intercambio por Conexión no es un primer recuerdo válido.
LMemoryArgBadSpecies = {0} Recuerdo: No se puede capturar la especie en el juego.
LMemoryArgSpecies = {0} Recuerdo: La especie no se puede capturar en el juego.
LMemoryCleared = Recuerdo: No están propiamente claros.
LMemoryF_0_Valid = {0} recuerdo es válido.
LMemoryFeelInvalid = {0} Recuerdo: Sentimiento inválido.
LMemoryHTFlagInvalid = No intercambiado: El entrenador actual no debería ser el entrenador anterior.
LMemoryHTGender = Género Inválido: {0}
LMemoryHTLanguage = Falta el idioma del HT.
LMemoryIndexArgHT = Debería tener un valor TextVar de recuerdo del entrenador anterior (en algún lugar).
LMemoryIndexFeel = {0} Recuerdo: Sentimiento debería ser indicado {1}.
LMemoryIndexFeelHT09 = Debería tener un valor de Sensación de Recuerdo entre 0-9.
LMemoryIndexID = {0} Recuerdo: Debería ser indicado {1}.
LMemoryIndexIntensity = {0} Recuerdo: La intensidad debería ser indicada {1}.
LMemoryIndexIntensityHT1 = Debería tener un valor de Intensidad de recuerdo de entrenador anterior (1ro).
LMemoryIndexIntensityMin = {0} Recuerdo: La intensidad debería ser al menos {1}.
LMemoryIndexLinkHT = Debería tener un recuerdo del entrenador anterior por intercambio.
LMemoryIndexVar = {0} Recuerdo: TextVar debería ser indicado {1}.
LMemoryMissingHT = Recuerdo: Falta el recuerdo del entrenador anterior.
LMemoryMissingOT = Recuerdo: Falta el recuerdo del entrenador original.
LMemorySocialTooHigh_0 = La sociabilidad deberia ser <= {0}
LMemorySocialZero = La sociabilidad deberia ser cero.
LMemoryStatAffectionHT0 = No intercambiado: El afecto con el entrenador anterior debería ser cero.
LMemoryStatAffectionOT0 = El afecto del EO debería de ser cero.
LMemoryStatEnjoyment = Los mimos deberían ser {0}.
LMemoryStatFriendshipHT0 = No intercambiado: La amistad con el entrenador anterior debería ser cero.
LMemoryStatFriendshipOTBaseEvent = La amistad con el EO de evento no coincide con el valor de base.
LMemoryStatFullness = La saciedad debería ser {0}.
LMetDetailTimeOfDay = Met Time of Day value is not within the expected range.
LMoveEggFIncompatible0_1 = {0} Movimiento Heredado. Incompatible con {1} Movimientos heredados.
LMoveEggIncompatible = Movimiento Huevo. Incompatible con Movimientos Huevo de Evento.
LMoveEggIncompatibleEvent = Movimiento Huevo de Evento. Incompatible con Movimiento Huevo normal.
LMoveEggInherited = Movimiento huevo heredado.
LMoveEggInheritedTutor = Movimiento heredado aprendido mediante tutor.
LMoveEggInvalid = No es un Movimiento Huevo esperado.
LMoveEggInvalidEvent = Movimiento Huevo. No esperable en un Huevo de Evento.
LMoveEggInvalidEventLevelUp = Movimiento heredado aprendido por nivel. No esperable en un Huevo de Evento.
LMoveEggInvalidEventLevelUpGift = Movimiento heredado aprendido por nivel. No esperable en un Huevo regalado.
LMoveEggInvalidEventTMHM = Movimiento heredado aprendido mediante MT/MO. No esperable en un Huevo de Evento.
LMoveEggInvalidEventTutor = Movimiento heredado aprendido mediante tutor. No esperable en un Huevo de Evento.
LMoveEggLevelUp = Movimiento heredado aprendido por nivel.
LMoveEggMissing = Faltan los Movimientos Huevo de Evento.
LMoveEggMoveGift = Movimiento Huevo. No esperable en un Huevo regalado.
LMoveEggTMHM = Movimiento heredado aprendido por MT/MO.
LMoveEventEggLevelUp = Movimiento heredado aprendido por nivel. Incompatible con Movimientos Huevo de Evento.
LMoveEvoFCombination_0 = Combinaciones de Movimientos no son compatibles con Movimientos de la evolución de {0}.
LMoveEvoFHigher = Movimientos de evolución incompatibles. {1} Movimiento aprendido a un nivel superior que otros {0} movimientos.
LMoveEvoFLower = Movimientos de evolución incompatibles. {0} Movimiento aprendido a un nivel inferior que otros {1} movimientos.
LMoveFDefault_0 = Movimiento por Defecto en Generación {0}.
LMoveFExpect_0 = Se esperaban los siguientes Movimientos: {0}
LMoveFExpectSingle_0 = Esperado: {0}
LMoveFLevelUp_0 = Aprendido por Nivel en Generación {0}.
LMoveFTMHM_0 = Aprendido mediante MT/MO en Generación {0}.
LMoveFTutor_0 = Aprendido mediante Tutor de Movimientos en Generación {0}.
LMoveKeldeoMismatch = Movimiento/Forma de Keldeo incorrecta.
LMoveNincada = Solo un movimiento de Ninjask permitido.
LMoveNincadaEvo = Aprendido al evolucionar a Nincada en Ninjask
LMoveNincadaEvoF_0 = Aprendido al evolucionar a Nincada en Ninjask en Generación {0}.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = Los PP del movimiento {0} están por encima de los permitidos.
LMovePPUpsTooHigh_0 = Move {0} PP Ups is above the amount allowed.
LMoveRelearnDexNav = No es un Movimiento de DexNav.
LMoveRelearnEgg = Movimiento Huevo base.
LMoveRelearnEggMissing = Faltan los Movimientos Huevo base.
LMoveRelearnFExpect_0 = Se esperaban los siguientes movimientos recordables: {0} ({1})
LMoveRelearnFMiss_0 = Faltan movimientos recordables: {0}
LMoveRelearnInvalid = No es un movimiento recordable.
LMoveRelearnNone = No se esperaba un movimiento recordable en esta casilla.
LMoveRelearnUnderground = No es un movimiento huevo posible en el Subsuelo.
LMoveShopAlphaMoveShouldBeMastered = El movimiento del alfa deberia estar marcado como dominado.
LMoveShopAlphaMoveShouldBeOther = El encuentro del alfa no es posible con este movimiento.
LMoveShopAlphaMoveShouldBeZero = Solo los Pokémon alfa pueden tener un movimiento de alfa.
LMoveShopMasterInvalid_0 = No se puede dominar manualmente {0}: no está permitido.
LMoveShopMasterNotLearned_0 = No se puede dominar manualmente {0}: no está entre los posibles movimientos recordables.
LMoveShopPurchaseInvalid_0 = No se puede comprar {0} en la tienda de movimientos.
LMoveSourceDefault = Movimiento por defecto.
LMoveSourceDuplicate = Movimiento duplicado.
LMoveSourceEgg = Movimiento Huevo.
LMoveSourceEggEvent = Movimiento Huevo de Evento.
LMoveSourceEmpty = Movimiento vacío.
LMoveSourceInvalid = Movimiento inválido.
LMoveSourceInvalidSketch = Movimiento inválido (Esquema).
LMoveSourceLevelUp = Aprendido por nivel.
LMoveSourceRelearn = Movimiento recordable.
LMoveSourceShared = Movimiento no recordable compartido.
LMoveSourceSharedF = Movimiento no recordable compartido en la {0}a Generación.
LMoveSourceSpecial = Movimiento especial no recordable.
LMoveSourceTMHM = Aprendido mediante MT/MO.
LMoveSourceTR = Marca inesperada del DT aprendido: {0}
LMoveSourceTutor = Aprendido mediante tutor.
LNickFlagEggNo = El Huevo no debe tener mote.
LNickFlagEggYes = El Huevo debe tener mote.
LNickInvalidChar = No se puede utilizar este mote.
LNickLengthLong = El mote es demasiado largo.
LNickLengthShort = El mote está vacío.
LNickMatchLanguage = El mote coincide con el de la especie.
LNickMatchLanguageEgg = El nombre del Huevo coincide con el idioma del mismo.
LNickMatchLanguageEggFail = El nombre del Huevo no coincide con el idioma del mismo.
LNickMatchLanguageFail = El mote no coincide con el de la especie.
LNickMatchLanguageFlag = Mote marcado, coincide con el de la especie.
LNickMatchNoOthers = El mote no coincide con el de otra especie.
LNickMatchNoOthersFail = El Mote coincide con el de otra especie (+Idioma).
LOT_IDEqual = El TID16 y el SID16 son iguales.
LOT_IDInvalid = La combinación TID y SID no es posible.
LOT_IDs0 = El TID16 y el SID16 son 0.
LOT_SID0 = El SID16 es cero.
LOT_SID0Invalid = El SID16 debería ser 0.
LOT_TID0 = El TID16 es cero.
LOTLanguage = El ID del lenguaje debería de ser {0}, no {1}.
LOTLong = El nombre del EO demasiado largo.
LOTShort = El nombre del EO es muy corto.
LOTSuspicious = Detalles del Entrenador Original sospechosos.
LPIDEncryptWurmple = La constante de encriptado para la evolución de Wurmple no coincide.
LPIDEncryptZero = La constante de encriptado no está establecida.
LPIDEqualsEC = La constante de encriptado coincide con el PID.
LPIDGenderMatch = El género coincide con el PID.
LPIDGenderMismatch = El género y el PID no coinciden.
LPIDNatureMatch = La naturaleza coincide con el PID.
LPIDNatureMismatch = La naturaleza y el PID no coinciden.
LPIDTypeMismatch = El PID del Tipo de Encuentro no es correcto.
LPIDZero = PID no establecido.
LPokerusDaysTooHigh_0 = El valor de días restantes del Pokérus es muy alto; se esperaba <= {0}.
LPokerusStrainUnobtainable_0 = No se puede obtener la cepa de Pokérus {0}.
LRibbonAllValid = Todas las cintas están justificadas.
LRibbonEgg = No se pueden recibir cintas siendo un Huevo.
LRibbonFInvalid_0 = Cintas inválidas:
LRibbonFMissing_0 = Cintas que faltan:
LRibbonMarkingAffixedF_0 = Cinta/marca pegada inválida: {0}
LRibbonMarkingFInvalid_0 = Marca inválida: {0}
LStatAlphaInvalid = Alfa incompatible.
LStatBattleVersionInvalid = La Versión de Batalla no está dentro del rango esperado.
LStatDynamaxInvalid = El nivel Dinamax no está dentro del rango esperado.
LStatGigantamaxInvalid = Gigamax incompatible.
LStatGigantamaxValid = La marca de Gigamax fue cambiada por Maxisopa.
LStatIncorrectCP = Los CP calculados no coinciden con el valor almacenado.
LStatIncorrectHeight = La altura calculada no coincide con el valor almacenado.
LStatIncorrectHeightCopy = La altura copiada no coincide con el valor original.
LStatIncorrectHeightValue = La altura no coincide con el valor esperado.
LStatIncorrectWeight = El peso calculado no coincide con el valor almacenado.
LStatIncorrectWeightValue = El peso no coincide con el valor esperado.
LStatInvalidHeightWeight = Los valores de altura/peso son estadísticamente improbables.
LStatNatureInvalid = La estadística de la naturaleza no está dentro del rango esperado.
LStatNobleInvalid = Pokémon señorial incompatible.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = El Superentrenamiento completo no es correcto.
LSuperDistro = Las misiones de Superentrenamiento distribuidas no están liberadas.
LSuperEgg = No se puede Superentrenar un Huevo.
LSuperNoComplete = No se puede tener activo el Superentrenamiento completo para el origen.
LSuperNoUnlocked = No se puede tener activo el Superentrenamiento desbloqueado para el origen.
LSuperUnavailable = Las misiones de Superentrenamiento no están disponibles en lo juegos visitados.
LSuperUnused = La casilla de Superentrenamiento no utilizada está marcada.
LTeraTypeIncorrect = El Teratipo no coincide con el esperado.
LTeraTypeMismatch = El Teratipo no coincide con ninguno de los tipos por defecto.
LTradeNotAvailable = No se puede intercambiar el encuentro al Entrenador actual.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = No se puede obtener la especie en los juegos de Consola Virtual.
LTransferCurrentHandlerInvalid = Entrenador actual no válido, se esperaba otro valor de los detalles del entrenador del archivo de guardado.
LTransferEgg = No se pueden transferir Huevos entre generaciones.
LTransferEggLocationTransporter = Localización inválida, se esperaba Pokétransfer.
LTransferEggMetLevel = Nivel de encuentro inválido para la transferencia.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Marcado como ilegal por el juego (abuso de glitch).
LTransferHTFlagRequired = El Entrenador actual no puede ser EO.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = El idioma del Entrenador actual no corresponde con el idioma esperado.
LTransferHTMismatchName = El nombre del Entrenador actual no corresponde con el nombre esperado.
LTransferMet = Localización inválida. Se esperaba Pokétransfer o Corona.
LTransferMetLocation = Localización mediante transferencia inválido.
LTransferMove = Movimiento de transferencia incompatible.
LTransferMoveG4HM = Despejar y Torbellino. Uno de estos movimientos debe de ser eliminado antes de ser transferido a la Generación 5.
LTransferMoveHM = MO de la {0} generación. Debería de haber sido eliminado antes de ser transferido a la Generación {1}.
LTransferNature = Naturaleza no válida en base a la Experiencia tras la transferencia.
LTransferNotPossible = Unable to transfer into current format from origin format.
LTransferObedienceLevel = Nivel de obediencia inválido.
LTransferOriginFInvalid0_1 = {0} origen no puede existir en la partida cargada ({1}) actualmente.
LTransferPIDECBitFlip = ¡El PID debería de ser igual a la CE [Con el primer dígito invertido]!
LTransferPIDECEquals = ¡El PID debería de ser igual a la CE!
LTransferPIDECXor = La constante de encriptado coincide con el PID variocolor.
LTransferTrackerMissing = Falta el rastreador de transferencia de Pokémon HOME.
LTransferTrackerShouldBeZero = El rastreador de transferencia de Pokémon HOME debería ser 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = Erreur interne.
L_ALegal = Légal !
L_AnalysisUnavailable = Analyse indisponible pour ce Pokémon.
L_AValid = Valide.
L_F0_1 = {0} : {1}
L_F0_M_1_2 = {0} Capacité {1} : {2}
L_F0_RM_1_2 = {0} Capacité réapprise {1} : {2}
L_FEncounterType_0 = Type de rencontres : {0}
L_FOriginSeed_0 = Origin Seed: {0}
L_FPIDType_0 = PID Type: {0}
L_SFishy = Suspicieux
L_SInvalid = Invalide
L_SNotImplemented = Non implémenté
L_SValid = Valide
L_XEnigmaBerry_0 = BAIE {0}
L_XHT = HT
L_XKorean = Coréen
L_XKoreanNon = Non-Coréen
L_XLocation = Location
L_XMatches0_1 = Correspondances : {0} {1}
L_XNickname = Nickname
L_XOT = DO
L_XRareFormEvo_0_1 = Evolves into form: {0} (rare: {1})
L_XWurmpleEvo_0 = Évolution de Chenipotte : {0}
LAbilityCapsuleUsed = Talent disponible avec la pilule Talent.
LAbilityFlag = Le Talent correspond à son index.
LAbilityHiddenFail = Talent incompatible avec type de rencontre.
LAbilityHiddenUnavailable = Ce Pokémon n'a pas de talent caché.
LAbilityMismatch = Rencontrer ce Pokémon de cette manière ne lui permet pas d'avoir ce Talent.
LAbilityMismatch3 = Le Talent ne correspond pas aux possibilités de Talent en Génération 3.
LAbilityMismatchFlag = Le Talent ne correspond pas à son index.
LAbilityMismatchGift = Talent non correspondant au Cadeau Mystère.
LAbilityMismatchGrotto = Les Pokémon des Trouées Cachées doivent avoir leur Talent caché.
LAbilityMismatchHordeSafari = Talent caché, Pokémon rencontré dans la nature (mais pas dans un Safari des amis ni dans une horde).
LAbilityMismatchPID = Le Talent ne correspond pas au PID du Pokémon.
LAbilityMismatchSOS = Talent caché, Pokémon rencontré dans la nature (mais pas en appels SOS).
LAbilityPatchRevertUsed = Capacité disponible avec l'annulation du patch de capacité.
LAbilityPatchUsed = Talent disponible avec le patch de Talent.
LAbilityUnexpected = Talent incompatible avec espèce / forme.
LAwakenedCap = La valeur AV individuelle ne peut pas être supérieure à {0}.
LAwakenedShouldBeValue = La valeur AV individuelle ({1}) doit être supérieure à {0}.
LBallAbility = Impossible d'avoir le talent caché avec cette Ball.
LBallEggCherish = Un Œuf ne peut pas être contenu dans une Mémoire Ball.
LBallEggMaster = Un Œuf ne peut pas être contenu dans une Master Ball.
LBallEnc = Type de Ball possible pour le type de rencontre actuel.
LBallEncMismatch = Type de Ball impossible pour le type de rencontre actuel.
LBallHeavy = Les espèces avec faible taux de capture et faible poids ne peuvent pas être capturées dans une Masse Ball (Gén. VII).
LBallNone = Aucune vérification réussie, Pokémon considéré illégal.
LBallSpecies = L'espèce ne peut pas être capturée avec cette Ball.
LBallSpeciesPass = Ball possible pour les espèces.
LBallUnavailable = Ball impossible à obtenir dans la génération du jeu.
LContestSheenTooHigh_0 = Contest Stat Sheen should be <= {0}.
LContestSheenTooLow_0 = Contest Stat Sheen should be >= {0}.
LContestZero = Les Stats de Concours doivent être 0.
LContestZeroSheen = Contest Stat Sheen should be 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = La date de rencontre est en dehors de la fenêtre de distribution.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 2 EVs restants.
LEffortAbove252 = Les EVs dans une seule statistique ne peuvent pas dépasser 252.
LEffortAbove510 = Le total d'EVs ne doit pas être supérieur à 510.
LEffortAllEqual = Les EVs sont tous égaux.
LEffortCap100 = Les EVs pour une statistique ne peuvent pas être au-dessus de 100 pour un Pokémon rencontré au niveau 100 en Génération 4.
LEffortEgg = Les Œufs ne peuvent pas recevoir d'EVs.
LEffortEXPIncreased = Tous les EVs sont à 0, mais ils sont au-dessus du niveau de rencontre.
LEffortShouldBeZero = Impossible de recevoir d'EVs.
LEffortUntrainedCap = Les EVs individuels sans changer le montant d'Expérience ne peuvent pas dépasser {0}.
LEggContest = Impossible d'augmenter les Stats de Concours à un Œuf.
LEggEXP = Les œufs ne peuvent pas recevoir d'expérience.
LEggFMetLevel_0 = Niveau Atteint Invalides, attendu {0}.
LEggHatchCycles = Cycles d'éclosion d'Œuf invalides.
LEggLocation = Il est possible de faire éclore l'Œuf au lieu de rencontre.
LEggLocationInvalid = L'œuf ne peut pas éclore sur le lieu de rencontre.
LEggLocationNone = Emplacement de l'œuf non valide, aucun prévu.
LEggLocationPalPark = Emplacement rencontré non valide, attendu Parc des Amis.
LEggLocationTrade = Vous pouvez faire éclore l'oeuf échangé au lieu de rencontre.
LEggLocationTradeFail = Lieu d'obtention d'Œuf invalide, impossible de faire un échange sous cette forme.
LEggMetLocationFail = L'œuf ne peut pas être obtenu au lieu de rencontre.
LEggNature = Les œufs ne peuvent pas avoir de nature statistique.
LEggPokeathlon = Les Œufs ne peuvent pas avoir de statistiques Pokéathlon.
LEggPokerus = L'Œuf ne peut pas être atteint par le Pokérus.
LEggPP = Impossible de modifier les PP d'un Œuf.
LEggPPUp = Impossible d'appliquer des PP Plus à un Œuf.
LEggRelearnFlags = Les œufs ne peuvent pas avoir de disques techniques marqués.
LEggShinyLeaf = Les Œufs ne peuvent pas avoir de feuille / couronne d'or.
LEggShinyPokeStar = Les œufs ne peuvent pas être une star de Pokéwood.
LEggSpecies = Cette espèce ne peut pas se reproduire.
LEggUnhatched = Œuf non-éclos valide.
LEncCondition = Rencontre de Pokémon sauvage valide à cet endroit.
LEncConditionBadRNGFrame = Impossible de générer une séquence RNG correspondant aux conditions de rencontre.
LEncConditionBadSpecies = Le Pokémon n'existe pas dans le jeu d'origine.
LEncConditionBlack = Rencontre de Pokémon sauvage valide à cet endroit (Flûte Noire).
LEncConditionBlackLead = Rencontre de Pokémon sauvage valide à cet endroit (Flûte Noire & Esprit Vital/Agitation/Pression)
LEncConditionDexNav = Rencontre de Pokémon sauvage valide à cet endoit (Navi-Dex).
LEncConditionLead = Rencontre de Pokémon sauvage valide à cet endroit (Esprit Vital/Agitation/Pression).
LEncConditionWhite = Rencontre de Pokémon sauvage valide à cet endroit (Flûte Blanche).
LEncConditionWhiteLead = Rencontre de Pokémon sauvage valide à cet endroit (Flûte Blanche & Esprit Vital/Agitation/Pression)
LEncGift = Impossible de trouver une rencontre avec un œuf d'événement dans le jeu d'origine.
LEncGiftEggEvent = Impossible de faire correspondre l'obtention de l'Œuf par évènement dans le jeu d'origine.
LEncGiftIVMismatch = Les IVs ne correspondent pas aux données Cadeau Mystère.
LEncGiftNicknamed = Ce Pokémon a été surnommé et est un Pokémon événementiel.
LEncGiftNotFound = Impossible de trouver une correspondance dans les Cadeaux Mystères.
LEncGiftPIDMismatch = Le PID du cadeau mystère obligatoire n'est pas correct.
LEncGiftShinyMismatch = Le cadeau mystère shiny est incorrect.
LEncGiftVersionNotDistributed = Cette version ne peut pas recevoir de Cadeau Mystère.
LEncInvalid = Impossible de trouver une correspondance de rencontre dans le jeu d'origine.
LEncMasteryInitial = Les indicateurs initiaux de maîtrise des capacités ne correspondent pas à l'état attendu de la rencontre.
LEncStaticMatch = Cadeau valide/rencontre statique.
LEncStaticPIDShiny = Pokémon shiny-locked défini comme étant chromatique.
LEncStaticRelearn = Le mouvement dé réapprentissage de la rencontre statique n'est pas correct.
LEncTradeChangedNickname = Le surnom du Pokémon reçu par échange in-game a été modifié.
LEncTradeChangedOT = Le DO du Pokémon reçu par échange in-game a été modifié.
LEncTradeIndexBad = L'index d'échange in-game n'est pas valide?
LEncTradeMatch = Échange in-game valide.
LEncTradeUnchanged = Le DO et le surnom d'un Pokémon lors d'un échange dans le jeu n'ont pas été modifiés.
LEncTypeMatch = Le type de rencontre correspond à la rencontre.
LEncTypeMismatch = Le type de rencontre ne correspond pas à la rencontre.
LEncUnreleased = Pokémon événementiel non officialisé.
LEncUnreleasedEMewJP = Mew non Japonais de l'île lointaine. Évènement non officialisé.
LEncUnreleasedHoOArceus = Arceus de Salle Originelle. Évènement non officialisé.
LEncUnreleasedPtDarkrai = Darkrai d'Île Nouvellelune hors Pokémon Platine. Évènement non officialisé.
LEncUnreleasedPtShaymin = Shaymin de Paradis Fleuri hors Pokémon Platine. Évènement non officialisé.
LEReaderAmerica = American E-Reader berry dans un fichier japonais.
LEReaderInvalid = E-Reader Berry Invalide .
LEReaderJapan = Japanese E-Reader Berry dans un fichier de sauvegarde international.
LEvoInvalid = Évolution invalide (conditions non satisfaites).
LEvoTradeReq = Le {0} échangé dans le jeu devrait évoluer vers {1}.
LEvoTradeReqOutsider = Le {0} étranger devrait évoluer en {1}.
LEvoTradeRequired = Une évolution restreinte à une version requiert un échange vers la version opposée. Un Dresseur Actuel est nécessaire.
LFateful = Rencontre spéciale in-game (fatidique).
LFatefulGiftMissing = Rencontre fatidique, aucune correspondance trouvée. Peut-être que la base de données des Cadeaux Mystère a été modifiée ?
LFatefulInvalid = La case Rencontre Fatidique ne doit pas être cochée.
LFatefulMissing = Flag de rencontre fatidique in-game manquant.
LFatefulMystery = Rencontre fatidique (Cadeau Mystère).
LFatefulMysteryMissing = Flag de rencontre fatidique par Cadeau Mystère manquant.
LFavoriteMarkingUnavailable = Le marquage des favoris n'est pas disponible.
LFormArgumentHigh = L'argument de forme est trop élevé pour le formulaire actuel.
LFormArgumentInvalid = L'argument de forme n'est pas valide.
LFormArgumentLow = L'argument de forme est trop faible pour le formulaire actuel.
LFormArgumentNotAllowed = L'argument de forme n'est pas autorisé pour cette rencontre.
LFormArgumentValid = L'argument de forme est valide.
LFormBattle = La Forme ne peut pas être obtenue en dehors d'un combat.
LFormEternal = Rencontre de fleur éternelle valide.
LFormEternalInvalid = Rencontre de fleur éternelle invalide.
LFormInvalidExpect_0 = La forme est invalide. Attendu {0}.
LFormInvalidGame = La Forme ne peut pas être obtenue dans le jeu actuel.
LFormInvalidNature = La Forme ne peut pas avoir cette nature.
LFormInvalidRange = Le nombre de forme est hors de portée. Attendu <= {0}, obtenu {1}.
LFormItem = L'objet tenu correspond à la forme.
LFormItemInvalid = L'objet tenu ne correspond pas à la forme.
LFormParty = La Forme ne peut pas exister en dehors de l'Équipe.
LFormPikachuCosplay = Seul Cosplay Pikachu peut avoir cette forme.
LFormPikachuCosplayInvalid = Cosplay Pikachu ne peut pas avoir cette forme par défaut.
LFormPikachuEventInvalid = L'événement Pikachu ne peut pas avoir cette forme par défaut.
LFormValid = La Forme est valide.
LFormVivillon = Motif de Prismillon valide.
LFormVivillonEventPre = Motif de Prismillon événementiel appliqué sur pré-évolution.
LFormVivillonInvalid = Motif de Prismillon invalide.
LFormVivillonNonNative = Non-native Vivillon pattern.
LG1CatchRateChain = Le taux de capture ne correspond à aucune espèce de la chaîne d'évolution Pokémon.
LG1CatchRateEvo = Le taux de capture correspond aux espèces sans rencontres. Un taux de capture d'une pré-évolution est attendu.
LG1CatchRateItem = Le taux de capture ne correspond pas à l'objet détenu valide de la génération 2.
LG1CatchRateMatchPrevious = Le taux de capture correspond à toutes les espèces de la chaîne d'évolution Pokémon.
LG1CatchRateMatchTradeback = Le taux de capture correspond à l'objet détenu valide de la génération 2.
LG1CatchRateNone = Le taux de capture ne correspond à aucune espèce de la chaîne d'évolution Pokémon ni à aucun objet détenue de la génération 2.
LG1CharNick = Le surnom contient des caractères indisponibles (génération 1/2).
LG1CharOT = Le DO de géneration 1/2 utilise des caractères indisponibles.
LG1GBEncounter = Pas de rencontre spéciale dans les jeux de Console Virtuelle.
LG1MoveExclusive = Mouvement exclusif de la génération 1. Incompatible avec les mouvements sans échange.
LG1MoveLearnSameLevel = Capacités incompatibless : elles sont apprenables dans Pokémon Rouge/Vert au même niveau dans Pokémon Jaune.
LG1MoveTradeback = Mouvement d'oeuf sans échange. Incompatible avec les mouvements exclusifs de la génération 1.
LG1OTEvent = Nom DO d'événement RBY incorrect.
LG1OTGender = DO féminin des générations 1 ou 2 invalide.
LG1Stadium = DO Pokémon Stadium incorrect.
LG1StadiumInternational = DO international de Pokémon Stadium valide.
LG1StadiumJapanese = DO japonais de Pokémon Stadium valide.
LG1TradebackPreEvoMove = Mouvement pré-évolution sans échange. Incompatible avec les mouvements exclusifs de la génération 1.
LG1Type1Fail = Type A non valide, ne correspond pas au type d'espèce.
LG1Type2Fail = Type B non valide, ne correspond pas au type d'espèce.
LG1TypeMatch1 = Type A valide, correspond au type d'espèces.
LG1TypeMatch2 = Type B valide, correspond au type d'espèces.
LG1TypeMatchPorygon = Porygon avec des valeurs de Type A et B valides.
LG1TypePorygonFail = Porygon avec valeurs du Type A et B invalides ; elles ne correspondent pas à une combinaison de types valide.
LG1TypePorygonFail1 = Porygon avec Type A invalide.
LG1TypePorygonFail2 = Porygon avec Type B invalide.
LG2InvalidTilePark = Rencontre par pêche dans le Parc National. Cases d'eau inatteignables.
LG2InvalidTileR14 = Rencontre par pêche à la Route 14 de Kanto. Cases d'eau inatteignables.
LG2InvalidTileSafari = Rencontre par pêche dans le Parc Safari de la 2ème génération. Zone inatteignable.
LG2InvalidTileTreeID = Vous avez trouvé un arbre inaccessible pour la rencontre avec Coup d'Boule Crystal qui correspond à OTID.
LG2InvalidTileTreeNotFound = Impossible de trouver un arbre pour la rencontre avec le Coup d'Boule Crystal qui correspond à OTID.
LG2OTGender = Les DO des jeux de console virtuelle autres que Crystal ne peuvent pas être des femmes.
LG2TreeID = Vous avez trouvé un arbre pour la rencontre de Coup d'Boule Crystal qui correspond à OTID.
LG3EReader = Pokémon Shadow E-reader non japonais. Rencontre non officialisé.
LG3OTGender = Le DO de Pokémon Colosseum / XD ne peut pas être une fille.
LG4InvalidTileR45Surf = Rencontre à la Route 45 de Johto en Surfant. Cases d'eau inatteignables.
LG5ID_N = Le nom / ID Dresseur / ID secret de N est incorrect.
LG5IVAll30 = Tous les IVs des Pokémon de N doivent être 30.
LG5OTGenderN = Les Pokémon de N doit avoir un genre masculin DO.
LG5PIDShinyGrotto = Les Pokémon capturés dans les Trouées cachées ne peuvent pas être chromatiques.
LG5PIDShinyN = Les Pokémon de N ne peuvent pas être chromatiques.
LG5SparkleInvalid = Le flag de l'éclat spécial des Pokémon de N ne doit pas être coché.
LG5SparkleRequired = Le flag de l'éclat spécial des Pokémon de N est manquant.
LGanbaruStatTooHigh = Une ou plusieurs valeurs du niveau d'effort sont supérieures à la limite naturelle de (10 - IV bonus).
LGenderInvalidNone = Les Pokémon asexués ne peuvent pas être genrés.
LGeoBadOrder = Mémoire géolocalisations : Vide présent.
LGeoHardwareInvalid = Géolocalisations : Le pays n'est pas inclus dans une région 3DS.
LGeoHardwareRange = Région de Console invalide.
LGeoHardwareValid = Géolocalisations : Le pays est inclus dans une région 3DS.
LGeoMemoryMissing = Mémoire géolocalisations : Des mémoires doivent être présentes.
LGeoNoCountryHT = Mémoire géolocalisations : Le nom du Dresseur actuel est présent mais n'a pas de pays précédent.
LGeoNoRegion = Mémoire géolocalisations : Région sans pays.
LHyperPerfectAll = Impossible de faire subir l'Entraînement Ultime à un Pokémon aux IVs parfaits.
LHyperPerfectOne = Impossible de faire subir l'Entraînement Ultime à une statistique aux IVs parfaits.
LHyperPerfectUnavailable = Impossible d'hyperformer un ou plusieurs IV.
LHyperTooLow_0 = Impossible de faire subir l'Entraînement Ultime à un Pokémon au-dessous du niveau {0}.
LItemEgg = Les Œufs ne peuvent pas tenir d'objet.
LItemUnreleased = L'objet tenu n'a pas encore été dévoilé.
LIVAllEqual_0 = Tous les IVs sont {0}.
LIVF_COUNT0_31 = Ce Pokémon doit avoir au moins {0} IVs parfaits.
LIVNotCorrect = Les IVs ne correspondent pas aux exigences de la rencontre.
LLevelEXPThreshold = Le montant d'Expérience actuel équivaut le palier du niveau défini.
LLevelEXPTooHigh = L'expérience actuelle dépasse le montant maximum pour le niveau 100.
LLevelMetBelow = Niveau actuel au-dessous du niveau de rencontre.
LLevelMetGift = Niveau de rencontre inégal au niveau défini par Cadeau Mystère.
LLevelMetGiftFail = Niveau actuel au-dessous du niveau défini par Cadeau Mystère.
LLevelMetSane = Le niveau actuel est au-dessus du niveau de rencontre.
LMarkValueOutOfRange_0 = Le marquage individuel à l'index {0} n'est pas dans la plage de valeurs autorisée.
LMarkValueShouldBeZero = Les drapeaux de marquage ne peuvent pas être mis en place.
LMarkValueUnusedBitsPresent = Le marquage des drapeaux utilise des bits au-delà de la plage accessible.
LMemoryArgBadCatch = Mémoire {0} : {0} n'a pas attrapé ce Pokémon.
LMemoryArgBadHatch = Mémoire {0} : {0} n'a pas éclos cet Œuf.
LMemoryArgBadHT = Mémoire : L'Œuf ne peut pas avoir de Mémoire sur son Dresseur Actuel.
LMemoryArgBadID = Mémoire {0} : Mémoire non obtenable dans Pokémon {0}.
LMemoryArgBadItem = Mémoire {0}: L'espèce ne peut pas tenir d'objet.
LMemoryArgBadLocation = Mémoire {0} : Localisation non obtenable dans Pokémon {0}.
LMemoryArgBadMove = Mémoire {0} : L'espèce ne peut pas apprendre cette capacité.
LMemoryArgBadOTEgg = Mémoire {0} : Un échange Link n'est pas une première Mémoire valide.
LMemoryArgBadSpecies = Mémoire {0} : Cette espèce est non capturable dans ce jeu.
LMemoryArgSpecies = Mémoire {0} : L'espèce est capturable dans le jeu.
LMemoryCleared = Mémoire : La Mémoire n'a pas été correctement vidée.
LMemoryF_0_Valid = La Mémoire {0} est valide.
LMemoryFeelInvalid = Mémoire {0} : Sentiment invalide.
LMemoryHTFlagInvalid = Non-échangés : Le Dresseur du Pokémon ne doit pas être le Dresseur actuel.
LMemoryHTGender = HT Genre invalide : {0}
LMemoryHTLanguage = La langue HT est manquante.
LMemoryIndexArgHT = Il doit avoir une valeur TextVar de la mémoire de l'entraîneur précédent (quelque part).
LMemoryIndexFeel = Mémoire {0} : Le sentiment doit être index {1}.
LMemoryIndexFeelHT09 = Il doit avoir une valeur de Sentiment entre 0 et 9.
LMemoryIndexID = Mémoire {0} : Doit être index {1}.
LMemoryIndexIntensity = Mémoire {0} : L'intensité doit être index {1}.
LMemoryIndexIntensityHT1 = Vous devriez avoir une valeur d'intensité de rappel de l'entraîneur précédent (1er).
LMemoryIndexIntensityMin = Mémoire {0} : L'intensité doit être d'au moins {1}.
LMemoryIndexLinkHT = Vous devriez avoir un souvenir de l'entraîneur précédent par échange.
LMemoryIndexVar = Mémoire {0} : TextVar doit être index {1}.
LMemoryMissingHT = Mémoire : Mémoire avec Dresseur actuel manquante.
LMemoryMissingOT = Mémoire : Mémoire avec DO manquante.
LMemorySocialTooHigh_0 = La statistique social devrait être <= {0}
LMemorySocialZero = La statistique social devrait être de zéro.
LMemoryStatAffectionHT0 = Non-échangés : L'affection avec le Dresseur Actuel doit être nulle.
LMemoryStatAffectionOT0 = L'Affection pour le DO doit être nulle.
LMemoryStatEnjoyment = Le plaisir doit être {0}.
LMemoryStatFriendshipHT0 = Non-échangés : L'amitié avec le Dresseur Actuel doit être nulle.
LMemoryStatFriendshipOTBaseEvent = L'amitié DO de l'événement ne correspond pas à l'amitié de base.
LMemoryStatFullness = La plénitude doit être {0}.
LMetDetailTimeOfDay = La valeur "Heure de la journée" n'est pas dans la fourchette attendue.
LMoveEggFIncompatible0_1 = {0} Déplacement hérité. Incompatible avec {1} mouvements hérités.
LMoveEggIncompatible = Mouvement des œufs. Incompatible avec les mouvements des œufs d'événement.
LMoveEggIncompatibleEvent = Mouvement des œufs d'événement. Incompatible avec le mouvement normal des œufs.
LMoveEggInherited = Capacité Œuf héritée.
LMoveEggInheritedTutor = Capacité de Donneur héritée.
LMoveEggInvalid = Ce n'est pas une capacité Œuf prévue.
LMoveEggInvalidEvent = Capacité Œuf imprévue chez un Œuf événementiel.
LMoveEggInvalidEventLevelUp = Capacité apprenable par montée en niveaux imprévue chez un Œuf événementiel.
LMoveEggInvalidEventLevelUpGift = Capacité héritée apprenable en montée en niveaux. Imprévu chez un Œuf reçu en cadeau.
LMoveEggInvalidEventTMHM = Capacité CT/CS héritée mais imprévue pour un Œuf par évènement.
LMoveEggInvalidEventTutor = Capacité apprenable par Donneur imprévue chez un Œuf événementiel.
LMoveEggLevelUp = Capacité apprenable par montée en niveaux héritée.
LMoveEggMissing = Capacité événementielle d'Œuf manquante.
LMoveEggMoveGift = Capacité Œuf imprévue chez un Œuf donné par cadeau.
LMoveEggTMHM = Capacité CT/CS héritée.
LMoveEventEggLevelUp = Capacité héritée apprenable en montant en niveaux. Incompatible avec les capacités d'Œuf événementiel.
LMoveEvoFCombination_0 = Le moveset est incompatible avec l'évolution de {0}.
LMoveEvoFHigher = Capacités d'évlution invalides. {1} capacité apprise à un niveau plus élevé que {0} autres.
LMoveEvoFLower = Capacités d'évlution invalides. {0} capacité apprise à un niveau plus bas que {1} autres.
LMoveFDefault_0 = Déplacement par défaut dans la génération {0}.
LMoveFExpect_0 = Les capacités suivantes étaient prévuess : {0}
LMoveFExpectSingle_0 = Attendu : {0}
LMoveFLevelUp_0 = Apprise par montée en niveaux dans la génération {0}.
LMoveFTMHM_0 = Apprise par CT/CS dans la génération {0}.
LMoveFTutor_0 = Apprise par Donneur de Capacités dans la génération {0}.
LMoveKeldeoMismatch = Combinaison forme/capacité invalide chez Keldeo.
LMoveNincada = Une seule capacité de Ninjask est permise.
LMoveNincadaEvo = Apprise en faisant évoluer Ningale en Ninjask.
LMoveNincadaEvoF_0 = Apprise en faisant évoluer Ningale en Ninjask dans la génération {0}.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = Le déplacement {0} PP est supérieur au montant autorisé.
LMovePPUpsTooHigh_0 = Move {0} PP Ups is above the amount allowed.
LMoveRelearnDexNav = Ce n'est pas un mouvement DexNav.
LMoveRelearnEgg = Mouvement de base de l'œuf.
LMoveRelearnEggMissing = Mouvement de base de l'oeuf manquant.
LMoveRelearnFExpect_0 = Capacités réapprises suivantes prévuess : {0} ({1})
LMoveRelearnFMiss_0 = Capacités réapprises manquantess : {0}
LMoveRelearnInvalid = Ce n'est pas un mouvement enregistrable.
LMoveRelearnNone = Pas de capacité réapprise prévue.
LMoveRelearnUnderground = Pas un mouvement d'œuf souterrain attendu.
LMoveShopAlphaMoveShouldBeMastered = La capacité du Baron devrait être marqué comme maitrisé.
LMoveShopAlphaMoveShouldBeOther = La rencontre avec le Baron ne peut être trouvée avec cet capacité Baron.
LMoveShopAlphaMoveShouldBeZero = Seuls les Barons peuvent avoir un ensemble de capacités Baron.
LMoveShopMasterInvalid_0 = Impossible de maîtriser manuellement {0} : non autorisé à maîtriser.
LMoveShopMasterNotLearned_0 = Impossible de maîtriser manuellement {0} : pas dans les mouvements de montée de niveau appris possibles.
LMoveShopPurchaseInvalid_0 = Impossible de sélectionner {0} au Maître des Capacités.
LMoveSourceDefault = Mouvement par défaut.
LMoveSourceDuplicate = Capacité dupliquée.
LMoveSourceEgg = Capacité d'Œuf.
LMoveSourceEggEvent = Capacité Œuf événementielle.
LMoveSourceEmpty = Capacité vide.
LMoveSourceInvalid = Capacité invalide.
LMoveSourceInvalidSketch = Capacité invalide (Gribouille).
LMoveSourceLevelUp = Apprise par montée en niveaux.
LMoveSourceRelearn = Capacité réapprenable.
LMoveSourceShared = Mouvement méconnaissable partagé.
LMoveSourceSharedF = Déplacement sans réapprentissage partagé dans la génération {0}.
LMoveSourceSpecial = Capacité non-réapprenable.
LMoveSourceTMHM = Apprise par CT/CS.
LMoveSourceTR = Marque inattendue du dossier technique appris: {0}
LMoveSourceTutor = Apprise par Donneur de Capacités.
LNickFlagEggNo = L'Œuf ne doit pas être surnommé.
LNickFlagEggYes = L'Œuf doit être surnommé.
LNickInvalidChar = Le Pokémon ne peut pas avoir ce surnom.
LNickLengthLong = Le surnom est trop long.
LNickLengthShort = Le surnom est vide.
LNickMatchLanguage = Le surnom correspond au nom d'une autre espèce.
LNickMatchLanguageEgg = La langue de l'Œuf correspond à son nom.
LNickMatchLanguageEggFail = Le nom de l'Œuf ne correspond pas à son nom dans la langue d'origine.
LNickMatchLanguageFail = Le surnom ne correspond pas au nom de l'espèce.
LNickMatchLanguageFlag = Surnom marqué, coïncide avec celui de l'espèce.
LNickMatchNoOthers = Le surnom ne correspond pas au nom d'une autre espèce.
LNickMatchNoOthersFail = Surnom correspond à un autre nom d'espèce (+ langue).
LOT_IDEqual = L'ID Dresseur est égal à l'ID Secret.
LOT_IDInvalid = TID and SID combination is not possible.
LOT_IDs0 = L'ID Dresseur et son ID secret sont nuls.
LOT_SID0 = L'ID Secret est 0.
LOT_SID0Invalid = L'ID secret doit être 0
LOT_TID0 = L'ID Dresseur est 0.
LOTLanguage = L'ID de langue doit être {0}, et non pas {1}.
LOTLong = Nom du DO trop long.
LOTShort = Nom du DO trop court.
LOTSuspicious = Détails DO suspicieux.
LPIDEncryptWurmple = La constante de chiffrement de Chenipotte ne correspond pas à son évolution.
LPIDEncryptZero = La constante de chiffrement n'a pas été générée.
LPIDEqualsEC = La constante de chiffrement est égale au PID.
LPIDGenderMatch = Le PID correspond au genre.
LPIDGenderMismatch = Le PID ne correspond pas au genre.
LPIDNatureMatch = Le PID correspond à la nature.
LPIDNatureMismatch = Le PID ne correspond pas à la nature.
LPIDTypeMismatch = Le PID ne correspond pas au type de rencontre.
LPIDZero = Le PID n'a pas été défini.
LPokerusDaysTooHigh_0 = Temps restant pour le Pokérus invalide. Attendu <= {0}.
LPokerusStrainUnobtainable_0 = La souche Pokérus {0} ne peut être obtenue.
LRibbonAllValid = Tous les rubans ont été comptabilisés.
LRibbonEgg = L'Œuf ne peut pas recevoir de Rubans.
LRibbonFInvalid_0 = Rubans invalides :
LRibbonFMissing_0 = Rubans manquants :
LRibbonMarkingAffixedF_0 = Ruban / marquage apposé non valide: {0}
LRibbonMarkingFInvalid_0 = Marquage non valide : {0}
LStatAlphaInvalid = Baron incompatible.
LStatBattleVersionInvalid = La version Battle n'est pas dans le rang attendue.
LStatDynamaxInvalid = Le niveau Dynamax n'est pas dans le rang attendue.
LStatGigantamaxInvalid = Gigamax incompatible.
LStatGigantamaxValid = La marque Gigamax a été changée via Max Soup.
LStatIncorrectCP = Le CP calculé ne correspond pas à la valeur enregistrée.
LStatIncorrectHeight = La hauteur calculée ne correspond pas à la valeur stockée.
LStatIncorrectHeightCopy = La hauteur de la copie ne correspond pas à la valeur d'origine.
LStatIncorrectHeightValue = La hauteur ne correspond pas à la valeur attendue.
LStatIncorrectWeight = Le poids calculé ne correspond pas à la valeur stockée.
LStatIncorrectWeightValue = Le poids ne correspond pas à la valeur attendue.
LStatInvalidHeightWeight = Les valeurs de taille et de poids sont statistiquement improbables.
LStatNatureInvalid = La Nature Stat n'est pas dans le rang attendue.
LStatNobleInvalid = Pokémon monarque incompatible.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = Contradiction avec le flag d'entraînement SPV complété.
LSuperDistro = Les missions Super Training distribuées ne sont pas publiées.
LSuperEgg = Un Œuf ne peut pas participer au Système de Perfectionnement Virtuel.
LSuperNoComplete = Impossible d'avoir un indicateur complet du Super Training actif pour les origines.
LSuperNoUnlocked = Impossible de déverrouiller le drapeau actif Super Training pour les origines.
LSuperUnavailable = Les missions SPV ne sont pas disponibles dans les jeux joués.
LSuperUnused = La case Super Training inutilisée est cochée.
LTeraTypeIncorrect = Le type de la Téracristallisation ne correspond pas à la valeur attendue.
LTeraTypeMismatch = Le type de la Téracristallisation ne correspond à aucun des types par défaut.
LTradeNotAvailable = La rencontre ne peut pas être échangée avec le dresseur actif.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = Espèce non obtenable dans jeu de Console Virtuelle.
LTransferCurrentHandlerInvalid = Valeur du gestionnaire courant non valide, les détails du dresseur pour le fichier de sauvegarde attendaient une autre valeur.
LTransferEgg = Un Œuf ne peut pas être transféré entre les générations.
LTransferEggLocationTransporter = Emplacement rencontré non valide, transfert Poké attendu.
LTransferEggMetLevel = Niveau atteint non valide pour le transfert.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Signalé comme illégal par le jeu (abus de glitch).
LTransferHTFlagRequired = L'entraîneur actuel ne sera DO.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = Le dresseur qui manipule ne correspond pas à la langue du dresseur attendu.
LTransferHTMismatchName = La manipulation du dresseur ne correspond pas au nom du dresseur attendu.
LTransferMet = Lieu de rencontre non valide. Pokétransfer ou Couronne attendus.
LTransferMetLocation = Pokémon transféré, endroit de rencontre invalide.
LTransferMove = Attaque de transfert incompatible.
LTransferMoveG4HM = Anti-Brume ou Siphon doivent être oubliées avant tout transfert vers la Génération 5.
LTransferMoveHM = CS de Génération {0}. Elle doit être oubliée avant de transférer le Pokémon vers la génération {1}.
LTransferNature = Nature invalide pour l'expérience de transfert.
LTransferNotPossible = Impossible de transférer dans le format actuel à partir du format d'origine.
LTransferObedienceLevel = Niveau d'obéissance invalide.
LTransferOriginFInvalid0_1 = L'origine de {0} ne peut pas exister dans cette sauvegarde ({1}).
LTransferPIDECBitFlip = Le PID doit être égal à EC [avec le bit supérieur retourné]!
LTransferPIDECEquals = PID doit être égal à EC!
LTransferPIDECXor = La constante de chiffrement correspond au PID shinyxored.
LTransferTrackerMissing = Pokémon HOME Transfer Tracker est manquant.
LTransferTrackerShouldBeZero = Pokémon HOME Transfer Tracker doit être à 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = Errore Interno.
L_ALegal = Legale!
L_AnalysisUnavailable = Anilisi non disponibile per questo Pokémon.
L_AValid = Valido.
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} Mossa {1}: {2}
L_F0_RM_1_2 = {0} Mossa Ricordabile {1}: {2}
L_FEncounterType_0 = Tipo Incontro: {0}
L_FOriginSeed_0 = Seed di origine: {0}
L_FPIDType_0 = Tipo PID: {0}
L_SFishy = Sospetto
L_SInvalid = Invalido
L_SNotImplemented = Non implementato
L_SValid = Valido
L_XEnigmaBerry_0 = BACCA{0}
L_XHT = HT
L_XKorean = Korean
L_XKoreanNon = Non-Korean
L_XLocation = Location
L_XMatches0_1 = Matches: {0} {1}
L_XNickname = Nickname
L_XOT = OT
L_XRareFormEvo_0_1 = Evolve nella forma: {0} (rara: {1})
L_XWurmpleEvo_0 = Evoluzione Wurmple: {0}
LAbilityCapsuleUsed = Abilità disponibile con la Capsula Abilità.
LAbilityFlag = Abilità corrispondente al Numero Abilità.
LAbilityHiddenFail = Abilità Nascosta non corrispondente al Tipo di Incontro.
LAbilityHiddenUnavailable = Abilità Nascosta non disponibile.
LAbilityMismatch = Abilità non corrispondente al Tipo di Incontro.
LAbilityMismatch3 = L'Abilità non corrisponde a quelle disponibili per la Gen 3.
LAbilityMismatchFlag = Abilità non corrispondente al Numero Abilità.
LAbilityMismatchGift = L'Abilità non corrisponde al Dono Segreto.
LAbilityMismatchGrotto = Le catture del Meandro Nascosto dovrebbero avere l'Abilità Nascosta.
LAbilityMismatchHordeSafari = Abilità Nascosta su un Pokémon non proveniente dal Safari o da un Gruppo.
LAbilityMismatchPID = l'Abilità non corrisponde al PID.
LAbilityMismatchSOS = Abilità Nascosta su un Pokémon non proveniente da una chiamata di aiuto.
LAbilityPatchRevertUsed = Ability available with Ability Patch Revert.
LAbilityPatchUsed = Abilità disponibile con il Cerotto Abilità.
LAbilityUnexpected = Abilità non valida per la Specie/Forma.
LAwakenedCap = AV individuali non possono essere superiori a {0}.
LAwakenedShouldBeValue = AV individuali ({1}) dovrebbero essere {0}.
LBallAbility = Impossibile ottenere l'Abilità con la Ball.
LBallEggCherish = Le uova non possono essere in Pregio Ball.
LBallEggMaster = Le uova non possono essere in Master Ball.
LBallEnc = Ball corretta per il tipo di incontro.
LBallEncMismatch = Questo tipo di incontro non può avere questa Ball.
LBallHeavy = Impossibile avere la Peso Ball per Pokémon leggeri con catch rate basso (gen VII).
LBallNone = Nessun controllo sodisfatto, si assume sia illegale.
LBallSpecies = Impossibile ottenere questa specie in questa Ball.
LBallSpeciesPass = Ball possibile per la specie.
LBallUnavailable = Ball inottenibile nella generazione di origine.
LContestSheenTooHigh_0 = Il Lustro dovrebbe essere <= {0}.
LContestSheenTooLow_0 = Il Lustro dovrebbe essere >= {0}.
LContestZero = Le statistiche delle Gare dovrebbero essere 0.
LContestZeroSheen = Il Lustro dovrebbe essere 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = La data di incontro è al di fuori del periodo di Distribuzione.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 2 EV rimanenti.
LEffortAbove252 = Gli EV non possono essere maggiori di 252.
LEffortAbove510 = Gli EV totali non possono essere maggiori di 510.
LEffortAllEqual = Gli EV sono tutti uguali.
LEffortCap100 = EV individuali per incontri di livello 100 in Gen 4 non possono essere maggiori di 100.
LEffortEgg = Le Uova non possono ricevere EV.
LEffortEXPIncreased = Gli EV sono Zero, ma il Pokémon è di livello superiore a quello di incontro.
LEffortShouldBeZero = Non può ricevere EV.
LEffortUntrainedCap = EV individuali senza guadagnare EXP non possono essere maggiori di {0}.
LEggContest = Le statistiche delle gare non possono crescere per un Uovo.
LEggEXP = Le Uova non possono ricevere esperienza.
LEggFMetLevel_0 = Livello di incontro invalido, valore previsto {0}.
LEggHatchCycles = Cicli di schiusa dell'Uovo invalidi.
LEggLocation = È possibile schiudere un Uovo nel luogo di incontro.
LEggLocationInvalid = Impossibile schiudere un Uovo nel luogo di incontro.
LEggLocationNone = Luogo dell'Uovo invalido, valore previsto None.
LEggLocationPalPark = Luogo di incontro invalido, valore previsto Parco Amici.
LEggLocationTrade = È possibile schiudere un Uovo scambiato nel luogo di incontro.
LEggLocationTradeFail = Il luogo di incontro non dovrebbe essere 'Scambio', se è un Uovo.
LEggMetLocationFail = Impossibile ottenre l'Uovo nel Luogo dell'Uovo.
LEggNature = Le Uova non possono avere la Natura delle Statistiche cambiata.
LEggPokeathlon = Le Uova non possono avere statistiche Pokéathlon.
LEggPokerus = Le Uova non possono essere infette da Pokérus.
LEggPP = Le Uova non possono avere modifiche ai PP.
LEggPPUp = Non si possono applicare PP Up alle Uova.
LEggRelearnFlags = Non sono previsti segnali di Mosse Ricordabili.
LEggShinyLeaf = Le Uova non possono avere Foglielucenti o la Corona di Foglie.
LEggShinyPokeStar = Le Uova non possono essere Star del Pokéwood.
LEggSpecies = Impossibile ottenere Uova di questa specie.
LEggUnhatched = Uovo non schiuso valido.
LEncCondition = Incontro selvatico valido nel luogo.
LEncConditionBadRNGFrame = Impossibile trovare una corrispondenza delle condizioni di incontro ad un possibile Frame RNG.
LEncConditionBadSpecies = La specie non esiste nel gioco di origine.
LEncConditionBlack = Incontro selvatico valido nel Luogo (Flauto Nero).
LEncConditionBlackLead = Incontro selvatico valido nel Luogo (Flauto Nero & Pressione/Tuttafretta/Spritovivo).
LEncConditionDexNav = Incontro selvatico valido nel Luogo (Navidex).
LEncConditionLead = Incontro selvatico valido nel Luogo (Pressione/Tuttafretta/Spiritovivo).
LEncConditionWhite = Incontro selvatico valido nel Luogo (Flauto Bianco).
LEncConditionWhiteLead = Incontro selvatico valido nel Luogo (Flauto Bianco & Pressione/Tuttafretta/Spiritovivo).
LEncGift = Impossibile trovare una corrispondenza per un Uovo donato dal gioco di origine.
LEncGiftEggEvent = Impossibile trovare una corrispondenza per un Uovo evento dal gioco di origine.
LEncGiftIVMismatch = Gli IV non corrispondono al Dono Segreto.
LEncGiftNicknamed = il Dono Segreto è stato soprannominato.
LEncGiftNotFound = Impossibile trovare una corrispondenza ai Doni Segreti nel Database.
LEncGiftPIDMismatch = Il PID non corrisponde a quello del Dono Segreto.
LEncGiftShinyMismatch = Il Dono Segreto non può essere Shiny.
LEncGiftVersionNotDistributed = Il Dono Segreto non può essere ricevuto in questa versione di gioco.
LEncInvalid = Impossibile trovare una corrispondenza per l'incontro nel gioco di origine.
LEncMasteryInitial = Initial move mastery flags do not match the encounter's expected state.
LEncStaticMatch = Dono/Incontro statico valido.
LEncStaticPIDShiny = L'Incontro statico non può essere shiny.
LEncStaticRelearn = L'incontro statico non può avere la mossa ricordabile.
LEncTradeChangedNickname = Il soprannome del Pokémon ottenuto con uno scambio in gioco è stato alterato.
LEncTradeChangedOT = Il Nome dell'AO di un Pokémon ottenuto con uno scambio in gioco è stato alterato.
LEncTradeIndexBad = Indice di scambio in gioco invalido?
LEncTradeMatch = Scambio in gioco valido.
LEncTradeUnchanged = Il nome dell'AO e il soprannome del Pokémon ottenuto con uno scambio in gioco sono validi.
LEncTypeMatch = Il tipo di incontro corrisponde all'incontro.
LEncTypeMismatch = il tipo di incontro non corrisponde all'incontro.
LEncUnreleased = Evento non rilasciato ufficialmente.
LEncUnreleasedEMewJP = L'evento di Mew è stato rilasciato solo in Giappone.
LEncUnreleasedHoOArceus = Arceus dallo Spazio Origine. L'Evento non è mai stato rilasciato.
LEncUnreleasedPtDarkrai = Darkrai dall'Isola Lunanuova non proveniente da Platino. L'Evento non è mai stato rilasciato.
LEncUnreleasedPtShaymin = Shaymin dal Paradiso Fiore non proveniente da Platino. L'Evento non è mai stato rilasciato.
LEReaderAmerica = Bacca da E-Reader Americano in un salvataggio Giapponese.
LEReaderInvalid = Bacca E-Reader invalida.
LEReaderJapan = Bacca da E-Reader Giapponese in un salvataggio Internazionale.
LEvoInvalid = Evoluzione non valida (o i requisiti di livello/scambio non sono soddisfatti).
LEvoTradeReq = Lo scambio in gioco {0} si sarebbe dovuto evolvere in {1}.
LEvoTradeReqOutsider = L'outsider {0} si sarebbe dovuto evolvere in {1}.
LEvoTradeRequired = L'evoluzione è specifica di una versione di gioco e richiede uno scambio. Il Pokémon deve avere un Ultimo Allenatore.
LFateful = Incontro mediante Evento Speciale in gioco.
LFatefulGiftMissing = Evento Speciale senza corrispondenze. I dati per il Dono Segreto sono stati contribuiti?
LFatefulInvalid = Evento Speciale non dovrebbe essere selezionato.
LFatefulMissing = Il segnale di Evento Speciale in gioco non è presente.
LFatefulMystery = Evento Speciale da Dono Segreto.
LFatefulMysteryMissing = Il segnale di Evento Speciale deve essere presente per il Dono Segreto.
LFavoriteMarkingUnavailable = Segnalino preferito non disponibile.
LFormArgumentHigh = L'Argomento di forma è troppo grande per la forma attuale.
LFormArgumentInvalid = L'Argomento di forma non è valido.
LFormArgumentLow = L'Argomento di forma è troppo basso per la forma attuale.
LFormArgumentNotAllowed = L'Argomento di forma non è disponibile per questo incontro.
LFormArgumentValid = L'Argomento di Forma è valido.
LFormBattle = La Forma non può esistere al di fuori di una battaglia.
LFormEternal = Incontro per Fiore Eterno valido.
LFormEternalInvalid = Incontro per Fiore Eterno non valido.
LFormInvalidExpect_0 = La forma è invalida, valore atteso: {0}.
LFormInvalidGame = La forma non può essere ottenuta nel gioco di origine.
LFormInvalidNature = La forma non può avere la natura.
LFormInvalidRange = Il conteggio della forma è fuori dall'indice. Valore previsto <= {0}, non {1}.
LFormItem = Lo strumento tenuto corrisponde alla forma.
LFormItemInvalid = Lo strumento tenuto non corrisponde alla forma.
LFormParty = La forma non può esistere al di fuori della squadra.
LFormPikachuCosplay = Solo Cosplay Pikachu può avere questa forma.
LFormPikachuCosplayInvalid = Cosplay Pikachu non può avere la forma base.
LFormPikachuEventInvalid = Pikachu Evento non può avere la forma base.
LFormValid = La forma è valida.
LFormVivillon = Il pattern di Vivillion è valido.
LFormVivillonEventPre = Il pattern di Vivillion evento è in una pre-evoluzione.
LFormVivillonInvalid = Il pattern di Vivillion non è valido.
LFormVivillonNonNative = Il pattern di Vivillion non è nativo.
LG1CatchRateChain = Il tasso di cattura non corrisponde a nessuna specie della catena evolutiva.
LG1CatchRateEvo = Il tasso di cattura corrisponde la specie senza incontri. Previsto il tasso di cattura di una pre-evoluzione.
LG1CatchRateItem = Il tasso di cattura non corrisponde ad un valido strumento tenuto nella seconda generazione.
LG1CatchRateMatchPrevious = Il tasso di cattura corrisponde tutte le specie della catena evolutiva.
LG1CatchRateMatchTradeback = Il tasso di cattura corrisponde ad un valido strumento tenuto nella seconda generazione.
LG1CatchRateNone = Il tasso di cattura non corrisponde a nessuna specie della catena evolutiva o ad alcun valido strumento tenuto nella seconda generazione.
LG1CharNick = Il soprannome da Gen1/2 utilizza caratteri proibiti.
LG1CharOT = Il nome allenatore da Gen1/2 utilizza caratteri proibiti.
LG1GBEncounter = Impossibile ottenere Incontri Speciali nei giochi Virtual Console.
LG1MoveExclusive = Mossa esclusiva della prima generazione. Incompatibile con le mosse non-tradeback.
LG1MoveLearnSameLevel = Mosse incompatibili. Imparate allo stesso livello in Rosso/Blu e Giallo.
LG1MoveTradeback = Mossa uovo non-tradeback. Incompatibile con le mosse esclusive da Gen1.
LG1OTEvent = Nome AO da evento RBG non corretto.
LG1OTGender = AO Femmina da Gen1/2 è invalido.
LG1Stadium = L'AO di Stadium è invalido.
LG1StadiumInternational = L'AO da Stadium Internazionale è valido.
LG1StadiumJapanese = L'AO da Stadium Giapponese è valido.
LG1TradebackPreEvoMove = Mossa pre-evolutiva non-tradeback. Incompatibile con le mosse esclusive di Gen1.
LG1Type1Fail = Tipo A invalido, non corrisponde al tipo specie.
LG1Type2Fail = Tipo B invalido, non corrisponde al tipo specie.
LG1TypeMatch1 = Tipo A valido, corrisponde al tipo specie.
LG1TypeMatch2 = Tipo B valido, corrisponde al tipo specie.
LG1TypeMatchPorygon = Porygon con tipo A e B valido.
LG1TypePorygonFail = Porygon con tipo A e B invalido. Non corrisponde a nessuna possibile combinazione.
LG1TypePorygonFail1 = Porygon con tipo A invalido.
LG1TypePorygonFail2 = Porygon con tipo B invalido.
LG2InvalidTilePark = Incontro da pesca al Parco Nazionale. La casella d'acqua non è raggiungibile.
LG2InvalidTileR14 = Incontro da pesca nel Percorso 14 di Kanto. La casella d'acqua non è raggiungibile.
LG2InvalidTileSafari = Incontro da pesca nella Zona Safari in Gen2. Zona irraggiungibile.
LG2InvalidTileTreeID = Trovato un albero irraggiungibile per un incontro Bottintesta su Cristallo che corrisponde al OTID.
LG2InvalidTileTreeNotFound = Impossibile trovare un incontro Bottintesta su Cristallo che corrisponda al OTID.
LG2OTGender = AO di giochi Virtual Console ad eccezione di Cristallo non possono essere femmina.
LG2TreeID = Trovato un albero per un incontro Bottintesta su Cristallo che corrisponde al OTID.
LG3EReader = Incontro Ombra E-Reader non Giapponese. Evento non rilasciato.
LG3OTGender = AO di Colosseum/XD non possono essere femmina.
LG4InvalidTileR45Surf = Incontro da surf nel Percorso 45 di Johto, la casella d'acqua è irraggiungibile.
LG5ID_N = Il Nome/TID16/SID16 di N non è corretto.
LG5IVAll30 = Tutti gli IV dei Pokémon di N dovrebbero essere 30.
LG5OTGenderN = I Pokémon di N devono avere il sesso dell'AO maschio.
LG5PIDShinyGrotto = Gli incontri del Meandro Nascosto non possono essere Shiny.
LG5PIDShinyN = I Pokémon di N non possono essere Shiny.
LG5SparkleInvalid = Il segnale speciale di luccichio dei Pokémon di N non dovrebbe essere ablitato.
LG5SparkleRequired = Segnale speciale di luccichio dei Pokémon di N assente.
LGanbaruStatTooHigh = Uno o più valori Ganbaru è oltre il limite naturale di (10 - IV bonus).
LGenderInvalidNone = I Pokémon senza sesso non dovrebbero avere un Sesso.
LGeoBadOrder = Memoria GeoLocation: Gap/Blank.
LGeoHardwareInvalid = Geolocation: La nazione non è disponibile nel 3DS.
LGeoHardwareRange = Regione della console non valida.
LGeoHardwareValid = Geolocation: la nazione è disponibile nel 3DS.
LGeoMemoryMissing = Memoria GeoLocation: le memorie dovrebbero essere presenti.
LGeoNoCountryHT = Memoria GeoLocation: è presente un nome per l'Ultimo Allenatore, ma non ha una nazione.
LGeoNoRegion = Memoria GeoLocation: la regione è senza nazione.
LHyperPerfectAll = Impossibile usare l'Allenamento Pro su un Pokémon con IV perfetti.
LHyperPerfectOne = Impossibile usare l'Allenamento Pro un IV perfetto.
LHyperPerfectUnavailable = L'Allenamento Pro non è possibile su alcun IV.
LHyperTooLow_0 = Impossibile usare l'Allenamento Pro su un Pokémon che non sia al livello {0}.
LItemEgg = Le Uova non possono tenere strumenti.
LItemUnreleased = Lo strumento tenuto non è stato rilasciato.
LIVAllEqual_0 = Tutti gli IV sono {0}.
LIVF_COUNT0_31 = Dovrebbe avere almeno {0} IVs = 31.
LIVNotCorrect = Gli IV non combaciano con i requisiti dell'incontro.
LLevelEXPThreshold = L'Esperienza è compatibile con il treshold del livello.
LLevelEXPTooHigh = Current experience exceeds maximum amount for level 100.
LLevelMetBelow = Il livello attuale è al di sotto del livello di incontro.
LLevelMetGift = Il livello di incontro non corrisponde al Dono Segreto.
LLevelMetGiftFail = Il livello attuale è al di sotto del livello del Dono Segreto.
LLevelMetSane = Il livello attuale non è al di sotto del livello di incontro.
LMarkValueOutOfRange_0 = Individual marking at index {0} is not within the allowed value range.
LMarkValueShouldBeZero = Marking flags cannot be set.
LMarkValueUnusedBitsPresent = Marking flags uses bits beyond the accessible range.
LMemoryArgBadCatch = Memoria {0}: {0} non lo ha catturato.
LMemoryArgBadHatch = Memoria {0}: {0} non lo ha schiuso.
LMemoryArgBadHT = Memoria: Non può avere memorie di un Ultimo Allenatore da Uovo.
LMemoryArgBadID = Memoria {0}: Impossibile ottenere la Memoria nella versione {0}.
LMemoryArgBadItem = Memoria {0}: La specie non può tenere questo oggetto.
LMemoryArgBadLocation = Memoria {0}: Impossibile avere il Luogo nella versione {0}.
LMemoryArgBadMove = Memoria {0}: La specie non può imparare questa mossa.
LMemoryArgBadOTEgg = Memoria {0}: Scambio in Link non è valida come prima memoria.
LMemoryArgBadSpecies = Memoria {0}: Impossibile catturare questa specie nel gioco.
LMemoryArgSpecies = Memoria {0}: La specie può essere catturata nel gioco.
LMemoryCleared = Memoria: Non ripulita correttamente.
LMemoryF_0_Valid = Memoria {0} valida.
LMemoryFeelInvalid = Memoria {0}: Sentimenti invalidi.
LMemoryHTFlagInvalid = Untraded: L'Allenatore Attuale non dovrebbe essere l'Ultimo Allenatore (non AO).
LMemoryHTGender = Genere dell'Ultimo Allenatore invalido: {0}
LMemoryHTLanguage = Lingua dell'Ultimo Allenatore mancante.
LMemoryIndexArgHT = Dovrebbe avere una memoria per l'Ultimo Allenatore TextVar.
LMemoryIndexFeel = Memoria {0}: il Sentimento dovrebbe essere di indice {1}.
LMemoryIndexFeelHT09 = Dovrebbe avere un feeling per l'Ultimo Allenatore di 0-9.
LMemoryIndexID = Memoria {0}: Dovrebbe essere di indice {1}.
LMemoryIndexIntensity = Memoria {0}: L'Intensità dovrebbe essere di indice {1}.
LMemoryIndexIntensityHT1 = Dovrebbe avere un valore di intensità per l'Ultimo Allenatore (primo).
LMemoryIndexIntensityMin = Memoria {0}: l'Intensità dovrebbe essere di almeno {1}.
LMemoryIndexLinkHT = Dovrebbe avere memoria di un Ultimo Allenatore per Scambio in Link.
LMemoryIndexVar = Memoria {0}: TextVar dovrebbe essere di indice {1}.
LMemoryMissingHT = Memoria: Le memorie per l'Ultimo Allenatore sono assenti.
LMemoryMissingOT = Memoria: memoria per l'Allenatore Originale mancante.
LMemorySocialTooHigh_0 = Social Stat dovrebbe essere <= {0}
LMemorySocialZero = Social Stat dovrebbe essere zero.
LMemoryStatAffectionHT0 = Untraded: l'Affetto per l'Ultimo Allenatore dovrebbe essere 0.
LMemoryStatAffectionOT0 = l'Affetto per l'AO dovrebbe essere 0.
LMemoryStatEnjoyment = Enjoyment dovrebbe essere {0}.
LMemoryStatFriendshipHT0 = Untraded: l'Amicizia per l'Ultimo Allenatore dovrebbe essere 0.
LMemoryStatFriendshipOTBaseEvent = L'Amicizia all'AO evento non corrisponde con l'amicizia base.
LMemoryStatFullness = Fullness dovrebbe essere {0}.
LMetDetailTimeOfDay = L'Ora di incontro non è all'interno della gamma attesa.
LMoveEggFIncompatible0_1 = {0} Mossa Ereditata. Incompatibile con {1} mossa ereditata.
LMoveEggIncompatible = Mossa uovo. Incompatibile con mosse uovo evento.
LMoveEggIncompatibleEvent = Mossa uovo evento. Incompatibile con mosse uovo normali.
LMoveEggInherited = Mossa uovo ereditata.
LMoveEggInheritedTutor = Mossa tutor ereditata.
LMoveEggInvalid = Non è una mossa uovo prevista.
LMoveEggInvalidEvent = Mossa uovo. Non prevista in un uovo evento.
LMoveEggInvalidEventLevelUp = Mossa ereditata acquisita con aumento di livello. Non prevista in un uovo evento.
LMoveEggInvalidEventLevelUpGift = Mossa ereditata acquisita con aumento di livelllo. Non prevista in un uovo donato.
LMoveEggInvalidEventTMHM = Mossa MT/MN ereditata. Non prevista in un uovo evento.
LMoveEggInvalidEventTutor = Mossa totor ereditata. Non prevista in un uovo evento.
LMoveEggLevelUp = Mossa ereditata acquisita tramite aumento di livello.
LMoveEggMissing = Mossa uovo evento mancante.
LMoveEggMoveGift = Mossa uovo. Non prevista in un uovo donato.
LMoveEggTMHM = Mossa MT/MN ereditata.
LMoveEventEggLevelUp = Mossa ereditata acquisita tramite aumento di livello. Incompatibile con mosse uovo evento.
LMoveEvoFCombination_0 = la combinazione di mosse non è compatibile con l'evoluzione di {0}.
LMoveEvoFHigher = Mosse evolutive incompatibili. {1} mossa imparata ad un livello pù alto delle altre {0} mosse.
LMoveEvoFLower = Mosse evolutive non compatibili. {0} mossa imparata ad un livello più basso delle altre {1} mosse.
LMoveFDefault_0 = Mossa base in generazione {0}.
LMoveFExpect_0 = Previste le seguenti mosse: {0}
LMoveFExpectSingle_0 = Expected: {0}
LMoveFLevelUp_0 = Acquisita per aumento di livello in gen {0}.
LMoveFTMHM_0 = Acquisita tramite MT/MN in gen {0}.
LMoveFTutor_0 = Insegnata da un Tutor Mosse in gen {0}.
LMoveKeldeoMismatch = Mossa/Forma di Keldeo non corrispondente.
LMoveNincada = Solo una mossa di Ninjask è concessa.
LMoveNincadaEvo = Acquisita evolvendo Nincada in Ninjask.
LMoveNincadaEvoF_0 = Acquisita evolvendo Nincada in Ninjask in gen {0}.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = I PP della mossa {0} sono oltre il massimo consentito.
LMovePPUpsTooHigh_0 = I PP Up della mossa {0} sono oltre il massimo consentito.
LMoveRelearnDexNav = Non è una mossa da Navidex prevista.
LMoveRelearnEgg = Mossa uovo base.
LMoveRelearnEggMissing = Mossa uovo base mancante.
LMoveRelearnFExpect_0 = Previste le seguenti mosse ricordabili: {0} ({1})
LMoveRelearnFMiss_0 = Mosse ricordabili mancanti: {0}
LMoveRelearnInvalid = Non è una mossa ricordabile prevista.
LMoveRelearnNone = Non è prevista una mossa ricordabile nello slot.
LMoveRelearnUnderground = Non è una mossa uovo sotterranea prevista.
LMoveShopAlphaMoveShouldBeMastered = La Mossa Alfa dovrebbe essere registrata come masterata.
LMoveShopAlphaMoveShouldBeOther = L'incontro Alfa non può essere trovato con questa mossa Alfa.
LMoveShopAlphaMoveShouldBeZero = Solo gli Alfa possono avere una mossa Alfa.
LMoveShopMasterInvalid_0 = Impossibile masterare manualmente {0}: non è permesso masterare.
LMoveShopMasterNotLearned_0 = Impossibile masterare manualmente {0}: non in possibili mosse acquisite per aumento di livello.
LMoveShopPurchaseInvalid_0 = Impossibile acquistare {0} dal negozio mosse.
LMoveSourceDefault = Mossa base.
LMoveSourceDuplicate = Mossa duplicata.
LMoveSourceEgg = Mossa uovo.
LMoveSourceEggEvent = Mossa uovo evento.
LMoveSourceEmpty = Mossa vuota.
LMoveSourceInvalid = Mossa invalida.
LMoveSourceInvalidSketch = Mossa invalida (Schizzo).
LMoveSourceLevelUp = Acquisita per aumento di livello.
LMoveSourceRelearn = Mossa ricordabile.
LMoveSourceShared = Shared Non-Relearn Move.
LMoveSourceSharedF = Shared Non-Relearn Move in Generation {0}.
LMoveSourceSpecial = Special Non-Relearn Move.
LMoveSourceTMHM = Acquisita tramite MT/MN.
LMoveSourceTR = Record per Disco Tecnico non aspettato: {0}
LMoveSourceTutor = Insegnata dal Tutor Mosse.
LNickFlagEggNo = L'Uovo non deve avere soprannomi.
LNickFlagEggYes = L'Egg deve avere il soprannome.
LNickInvalidChar = Non può avere questo soprannome.
LNickLengthLong = Soprannome troppo lungo.
LNickLengthShort = Il soprannome è vuoto.
LNickMatchLanguage = Il soprannome è uguale alla specie.
LNickMatchLanguageEgg = L'Uovo corrisponde al nome in lingua dell'Uovo.
LNickMatchLanguageEggFail = L'uovo non corrisponde al nome in lingua dell'Uovo.
LNickMatchLanguageFail = Il soprannome non corrisponde alla specie.
LNickMatchLanguageFlag = Soprannome segnalato, corrisponde al nome della specie.
LNickMatchNoOthers = Il soprannome non corrisponde al nome di un altra specie.
LNickMatchNoOthersFail = Il soprannome corrisponde al nome di un'altra specie (+language).
LOT_IDEqual = TID16 e SID16 sono uguali.
LOT_IDInvalid = la combinazione di TID e SID non è possibile.
LOT_IDs0 = TID16 e SID16 sono 0.
LOT_SID0 = SID16 è zero.
LOT_SID0Invalid = SID16 dovrebbe essere 0.
LOT_TID0 = TID16 è zero.
LOTLanguage = Language ID dovrebbe essere {0}, non {1}.
LOTLong = Nome AO troppo lungo.
LOTShort = Nome AO troppo corto.
LOTSuspicious = Dettagli dell'AO sospetti.
LPIDEncryptWurmple = Wurmple evolution Encryption Constant mismatch.
LPIDEncryptZero = Encryption Constant non impostata.
LPIDEqualsEC = Encryption Constant uguale al PID.
LPIDGenderMatch = Il sesso combacia con il PID.
LPIDGenderMismatch = Il sesso non combacia con il PID.
LPIDNatureMatch = La Natura combacia il PID.
LPIDNatureMismatch = La Natura non combacia con il PID.
LPIDTypeMismatch = PID+ correlation does not match what was expected for the Encounter's type.
LPIDZero = Il PID non è impostato.
LPokerusDaysTooHigh_0 = I giorni di Pokérus rimanenti sono troppi, previsto <= {0}.
LPokerusStrainUnobtainable_0 = Pokérus Strain {0} non può essere ottenuta.
LRibbonAllValid = Tutti i fiocchi sono stati contabilizzati.
LRibbonEgg = Non può avere fiocchi da Uovo.
LRibbonFInvalid_0 = Fiocchi invalidi:
LRibbonFMissing_0 = Fiocchi mancanti:
LRibbonMarkingAffixedF_0 = Fioccho o Emblema fissato invalido: {0}
LRibbonMarkingFInvalid_0 = Emblema invalido: {0}
LStatAlphaInvalid = Alfa non corrispondente.
LStatBattleVersionInvalid = la Versione Lotta non è in un range accettabile.
LStatDynamaxInvalid = Il Livello Dynamax non è in un range accettabile.
LStatGigantamaxInvalid = Gigamax non corrispondente.
LStatGigantamaxValid = Gigamax ottenuto con la Zuppamax.
LStatIncorrectCP = I PL calcolati non combaciano con il valore nei dati.
LStatIncorrectHeight = L'Altezza calcolata non corrisponde con il valore nei dati.
LStatIncorrectHeightCopy = Copy Height non corrisponde il valore originale.
LStatIncorrectHeightValue = L'Altezza non combacia con il valore previsto.
LStatIncorrectWeight = Il Peso calcolato non corrisponde con il valore nei dati.
LStatIncorrectWeightValue = Il Peso non cirrsponde con il valore previsto.
LStatInvalidHeightWeight = Il valore di Altezza e Peso è statisticamente improbabile.
LStatNatureInvalid = La Natura delle Statistiche non è in un range accettabile.
LStatNobleInvalid = Sgnale Nobile non corrispondente.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = Segnale di completamento del Super Allenamento non corrispondente.
LSuperDistro = Le missioni evento per il Super Allenamento non sono state rilasciate.
LSuperEgg = Un Uovo non può partecipare al Super Allenamento.
LSuperNoComplete = Non può aver completato il Super Allenamento per l'origine.
LSuperNoUnlocked = Non può avere il segnale di Sblocco Super Allenamento per l'origine.
LSuperUnavailable = Le missioni di Super Allenamento non sono disponibili nei giochi visitati.
LSuperUnused = Il segnale inutilizzato per il Super Allenamento è stato abilitato.
LTeraTypeIncorrect = Il Tera Tipo non corrisponde al valore atteso.
LTeraTypeMismatch = Il Tera Tipo non corrisponde a nessuno dei due tipi base.
LTradeNotAvailable = Il Pokémon non può essere scambiato all'Allenatore attuale.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = Il Pokémon trasferito da una generazione passata non è stato trasferito correttamente, o non è compatibile con questo salvataggio.
LTransferCurrentHandlerInvalid = Il valore dell'Ultimo Allenatore è invalido, i dettagli allenatori del salvataggio non sono corretti.
LTransferEgg = Impossibile tarsferire Uova tra Generazioni diverse.
LTransferEggLocationTransporter = Luogo di incontro non valido, previsto Pokétrasporto.
LTransferEggMetLevel = Livello di incontro non valido per il trasferimento.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Segnato come Illegale dal gioco (abuso di glitch o clonazione).
LTransferHTFlagRequired = l'Allenatore Originale non può essere l'Ultimo Allenatore.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = La lingua dell'Ultimo Allenatore non corrisponde al valore atteso.
LTransferHTMismatchName = Il nome dell'Ultimo Allenatore non corrisponde al valore atteso.
LTransferMet = Luogo di incontro invalido, previsto Pokétrasporto o Corona.
LTransferMetLocation = Luogo di trasferimento non valido.
LTransferMove = Mossa di trasferimento non valida.
LTransferMoveG4HM = Scacciabruma e Mulinello. Una delle due mosse deve essere rimossa prima di poter avviare il trasferimento verso Gen 5.
LTransferMoveHM = MN di {0} Gen. Deve essere rimossa prima di poter avviare il trasferimento verso Gen {1}.
LTransferNature = Natura non valida per il processo di trasferimento.
LTransferNotPossible = Impossibile trasferire il Pokémon dal formato originale al formato attuale.
LTransferObedienceLevel = Livello di Obbedienza invalido.
LTransferOriginFInvalid0_1 = L'origine {0} non può esistere nell'attuale ({1}) file di salvataggio.
LTransferPIDECBitFlip = Il PID dovrebbe essere uguale alla EC [con i bit superiori flippati]!
LTransferPIDECEquals = Il PID dovrebbe essere uguale alla EC!
LTransferPIDECXor = La Encryption Constant corrisponde ad un PID shiny.
LTransferTrackerMissing = Il codice di monitoraggio di Pokémon Home è mancante.
LTransferTrackerShouldBeZero = Il codice di monitoraggio di Pokémon Home dovrebbe essere 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = 内部エラー
L_ALegal = 正規
L_AnalysisUnavailable = このポケモンは分析できません
L_AValid = 有効
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} 技 {1}: {2}
L_F0_RM_1_2 = {0} 思い出し技 {1}: {2}
L_FEncounterType_0 = エンカウンタータイプ: {0}
L_FOriginSeed_0 = 元のシード: {0}
L_FPIDType_0 = 性格値: {0}
L_SFishy = 怪しい
L_SInvalid = エラー
L_SNotImplemented = 実装されていません
L_SValid = 有効
L_XEnigmaBerry_0 = {0}のみ
L_XHT = 現在のトレーナー
L_XKorean = 韓国
L_XKoreanNon = 韓国以外
L_XLocation = Location
L_XMatches0_1 = 一致: {0} {1}
L_XNickname = Nickname
L_XOT = 元々のトレーナー
L_XRareFormEvo_0_1 = 次のフォルムに進化: {0} (レア: {1})
L_XWurmpleEvo_0 = ケムッソの進化: {0}
LAbilityCapsuleUsed = とくせいカプセルを使うことで使用可能な特性です。
LAbilityFlag = 特性が特性番号と一致。
LAbilityHiddenFail = エンカウントタイプに対して、特性が隠れ特性ではありません。
LAbilityHiddenUnavailable = 隠れ特性にはできません。
LAbilityMismatch = 特性がエンカウントタイプと一致しません。
LAbilityMismatch3 = 第3世代のポケモンの特性と一致しません。
LAbilityMismatchFlag = 特性の番号が一致しません。
LAbilityMismatchGift = 特性がふしぎなおくりものデータベースと一致しません。
LAbilityMismatchGrotto = 隠し穴で捕まえたポケモンは、必ず隠れ特性でなければなりません。
LAbilityMismatchHordeSafari = 群れバトル/フレンドサファリ産ではない隠れ特性です。
LAbilityMismatchPID = 特性と性格値が一致しません。性格値を再生成してください。
LAbilityMismatchSOS = 乱入バトル産ではない隠れ特性です。
LAbilityPatchRevertUsed = とくせいパッチで元に戻すことで使用可能な特性です。
LAbilityPatchUsed = とくせいパッチを使うことで使用可能な特性です。
LAbilityUnexpected = その種族/フォルムでは、この特性は無効です。
LAwakenedCap = 各覚醒値は {0} を超えることはできません。
LAwakenedShouldBeValue = 各覚醒値 ({1}) は {0} を超えることはできません。
LBallAbility = そのボールでは隠れ特性の個体を捕獲できません。
LBallEggCherish = プレシャルボールは遺伝できません。
LBallEggMaster = マスターボールは遺伝できません。
LBallEnc = エンカウントタイプに合った正規のボールです。
LBallEncMismatch = このボールでは捕獲できません。
LBallHeavy = ヘビーボールのバグにより、捕獲は不可能です。SMのみ
LBallNone = 改造個体の可能性があります。
LBallSpecies = このボールでは捕獲できません。
LBallSpeciesPass = ポケモンによっては捕獲可能なボール。
LBallUnavailable = 元の世代では入手できないボール。
LContestSheenTooHigh_0 = けづやは <= {0} でなければなりません。
LContestSheenTooLow_0 = けづやは >= {0} でなければなりません。
LContestZero = コンディションは0でなければなりません。
LContestZeroSheen = けづやは0でなければなりません。
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = 出会った日が配布期間外です。
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 努力値が2残っています。
LEffortAbove252 = 努力値は1つにつき252までです。
LEffortAbove510 = 努力値の合計は510までです。
LEffortAllEqual = 努力値は全て等しいです。
LEffortCap100 = 第世代で出会ったレベルが100の場合、努力値はそれぞれ100を超えることはできません。
LEffortEgg = タマゴに努力値を振ることはできません。
LEffortEXPIncreased = 努力値は全て0ですが、出会ったレベルを超えています。
LEffortShouldBeZero = 努力値を振ることはできません。
LEffortUntrainedCap = 経験値を得ていないポケモンの努力値は {0} を超えることはできません。
LEggContest = タマゴはコンディションを上げることはできません。
LEggEXP = タマゴは経験値を得ることはできません。
LEggFMetLevel_0 = 出会ったレベルが無効です。 {0} にしてください。
LEggHatchCycles = 孵化サイクルが無効です。
LEggLocation = 出会った場所でタマゴを孵化させることが可能です。
LEggLocationInvalid = 出会った場所でタマゴを孵化させることができません。
LEggLocationNone = もらった場所が無効です。
LEggLocationPalPark = 出会った場所が無効です、パルパークにする必要があります。
LEggLocationTrade = 出会った場所で交換したタマゴを孵化させることができます。
LEggLocationTradeFail = もらった場所が無効です。タマゴの状態で交換してはいけません。
LEggMetLocationFail = そのもらった場所では、タマゴを入手できません。
LEggNature = タマゴはミントで性格変更できません。
LEggPokeathlon = タマゴはポケスロンのステータスを変更できません。
LEggPokerus = タマゴはポケルスに感染しません。
LEggPP = タマゴは技のPPを変更することはできません。
LEggPPUp = タマゴにポイントアップは使用できません
LEggRelearnFlags = 技を思い出すフラグがないと思われます。
LEggShinyLeaf = タマゴに『かがやくはっぱ/冠』を設定することはできません。
LEggShinyPokeStar = タマゴにポケウッドのスターを付与することはできません。
LEggSpecies = このポケモンのタマゴは入手できません。
LEggUnhatched = 孵化していない正規のタマゴ。
LEncCondition = 正規の場所で会った野生のポケモン。
LEncConditionBadRNGFrame = Unable to match encounter conditions to a possible RNG frame.
LEncConditionBadSpecies = このポケモンはこのゲームに登場しません。
LEncConditionBlack = 正規な場所(くろいビードロ使用)での野生産ポケモンです。
LEncConditionBlackLead = 正規な場所(くろいビードロやプレッシャー/はりきり/やるき)での野生産ポケモンです。
LEncConditionDexNav = 正規な場所(ずかんナビ)での野生産ポケモンです。
LEncConditionLead = 正規な場所(プレッシャー/はりきり/やるき)での野生産ポケモンです。
LEncConditionWhite = 正規な場所(しろいビードロ使用)での野生産ポケモンです。
LEncConditionWhiteLead = 正規な場所(しろいビードロやプレッシャー/はりきり/やるき)での野生産ポケモンです。
LEncGift = 元々のゲームでのタマゴのエンカウントと一致しません。
LEncGiftEggEvent = 元々のゲームのタマゴイベントのエンカウントと一致しません。
LEncGiftIVMismatch = ふしぎなおくりものデータベースの個体値と一致しません。
LEncGiftNicknamed = イベントで入手できるポケモンにニックネームがつけられています。
LEncGiftNotFound = ふしぎなおくりものデータベースと一致しません。
LEncGiftPIDMismatch = ふしぎなおくりものの性格値不一致を修正しました。
LEncGiftShinyMismatch = ふしぎなおくりものデータベースとの色(色違い)が一致しません。
LEncGiftVersionNotDistributed = このバージョンではふしぎなおくりものを受け取れません。
LEncInvalid = エンカウントエラー
LEncMasteryInitial = 予想されるエンカウントと技の皆伝状況が一致しません。
LEncStaticMatch = イベント/固定シンボル等
LEncStaticPIDShiny = 固定シンボルエンカウント等の色(色違いか)が一致しません。
LEncStaticRelearn = 固定シンボルエンカウント等の思い出し技が一致しません。
LEncTradeChangedNickname = ゲーム内交換のニックネームが変更されています。
LEncTradeChangedOT = ゲーム内交換の親名が変更されています。
LEncTradeIndexBad = In-game Trade invalid index?
LEncTradeMatch = 正規のゲーム内交換。
LEncTradeUnchanged = ゲーム内交換:元のトレーナーとニックネームは変更されていません。
LEncTypeMatch = エンカウントタイプが一致。
LEncTypeMismatch = エンカウントタイプが一致しません。
LEncUnreleased = 未解禁イベント
LEncUnreleasedEMewJP = 日本産以外のさいはてのことう産ミュウは解禁されていません。
LEncUnreleasedHoOArceus = はじまりのま産アルセウスは解禁されていません。
LEncUnreleasedPtDarkrai = プラチナ以外のダークライは解禁されていません。
LEncUnreleasedPtShaymin = プラチナ以外のシェイミは解禁されていません。
LEReaderAmerica = 日本のセーブデータに海外産のナゾのみが存在します。
LEReaderInvalid = このナゾのみは無効です。
LEReaderJapan = 海外のセーブデータに、日本産のナゾのみが存在します。
LEvoInvalid = その進化は無効です。(レベルが満たない/通信進化が必要)
LEvoTradeReq = ゲーム内交換により {0} は {1} に進化します。
LEvoTradeReqOutsider = 交換した {0} は必ず {1} に進化します。
LEvoTradeRequired = バージョン固有の進化には、もう一方のバージョンへの交換が必要です。
LFateful = ゲーム内でのうんめいてきなであいポケモン。
LFatefulGiftMissing = 一致する出会いがない、うんめいてきなであいポケモンです。ふしぎなおくりものデータはありますか?
LFatefulInvalid = 『うんめいてきなであい』のチェックを外してください。
LFatefulMissing = 『うんめいてきなであい』にチェックを入れてください。
LFatefulMystery = ふしぎなおくりもの産の『うんめいてきなであい』
LFatefulMysteryMissing = 『うんめいてきなであい』にチェックを入れてください。
LFavoriteMarkingUnavailable = お気に入りマークは使用できません。
LFormArgumentHigh = フォルムの引数が現在のフォルムには高すぎます。
LFormArgumentInvalid = フォルムの引数が無効です。
LFormArgumentLow = フォルムの引数が現在のフォルムには低すぎます。
LFormArgumentNotAllowed = このエンカウントタイプでは、フォルムの引数は許可されていません。
LFormArgumentValid = フォルムの引数は有効です。
LFormBattle = このフォルムはバトル中以外では存在できません。
LFormEternal = 有効なえいえんのはな個体。
LFormEternalInvalid = 無効なえいえんのはな個体。
LFormInvalidExpect_0 = フォルムは不正です。フォルムのインデックスを {0} にしてください。
LFormInvalidGame = このフォルムは元々のゲームでは獲得できません。
LFormInvalidNature = フォルムと性格が不一致です。
LFormInvalidRange = フォルムの数が範囲外です。予想:<= {0},取得したのは {1} です。
LFormItem = 持ち物とフォルムは一致しています。
LFormItemInvalid = 持ち物とフォルムが一致しません。
LFormParty = このフォルムは手持ちの外では存在できません。
LFormPikachuCosplay = このフォルムはおきがえピカチュウのみがなれます。
LFormPikachuCosplayInvalid = おきがえピカチュウは通常フォルムにはなれません。
LFormPikachuEventInvalid = イベント(帽子)ピカチュウは通常フォルムにはなれません。
LFormValid = フォルムは正常です。
LFormVivillon = 正常なビビヨンの模様。
LFormVivillonEventPre = 進化前のビビヨンのイベント模様。
LFormVivillonInvalid = 不正なビビヨンの模様。
LFormVivillonNonNative = Non-native Vivillon pattern.
LG1CatchRateChain = 捕獲率がどのポケモンの進化パターンとも一致しません。
LG1CatchRateEvo = 野生以外で捕獲したポケモンの捕獲率。進化前の捕獲率を想定されます。
LG1CatchRateItem = 捕獲率が第2世代の正規の持ち物と一致しません。
LG1CatchRateMatchPrevious = 捕獲率がポケモンの進化パターンと一致します。
LG1CatchRateMatchTradeback = 捕獲率が第2世代の正規の持ち物と一致します。
LG1CatchRateNone = 捕獲率がポケモンの進化パターンや、第2世代の持ち物とも一致しません。
LG1CharNick = 第1世代、第世代では使用できない文字がニックネームに含まれています。
LG1CharOT = 第1世代、第世代では使用できない文字がトレーナー名に含まれています
LG1GBEncounter = VCでは特別なポケモンは入手できません。
LG1MoveExclusive = 第1世代専用の技。タイムカプセルを使用する技と両立できません。
LG1MoveLearnSameLevel = 両立できない技。赤/緑とピカチュウで同じレベルで覚えます。
LG1MoveTradeback = タイムカプセルを使用しないタマゴ技。第1世代の専用技とは両立できません。
LG1OTEvent = 第1世代イベントでのトレーナー名が正しく有りません。
LG1OTGender = 第1世代、第2世代では女性トレーナーは選択できません。
LG1Stadium = ポケモンスタジアムのトレーナー名が間違っています。
LG1StadiumInternational = 正規の海外版のポケモンスタジアムのトレーナー名。
LG1StadiumJapanese = 正規の日本のポケモンスタジアムのトレーナー名。
LG1TradebackPreEvoMove = タイムカプセルをしていない進化前技。第1世代の専用技とは両立できません。
LG1Type1Fail = 不正のタイプA、種族タイプと一致しません。
LG1Type2Fail = 不正のタイプB、種族タイプと一致しません。
LG1TypeMatch1 = 正規のタイプA、種族タイプと一致します。
LG1TypeMatch2 = 正規のタイプB、種族タイプと一致します。
LG1TypeMatchPorygon = タイプAとBの値を持つ正規なポリゴン。
LG1TypePorygonFail = タイプAとBの値を持つ不正なポリゴン。有効な組み合わせと一致しません。
LG1TypePorygonFail1 = タイプAの値を持つ不正なポリゴン。
LG1TypePorygonFail2 = タイプBの値を持つ不正なポリゴン。
LG2InvalidTilePark = しぜんこうえん(2世代)の釣りエンカウント。正規では到達できない場所。
LG2InvalidTileR14 = 14ばんどうろ(2世代)の釣りエンカウント。正規では到達できない場所。
LG2InvalidTileSafari = 第2世代のサファリゾーンでの釣りエンカウント。正規では到達不可能。
LG2InvalidTileTreeID = トレーナーIDと一致するクリスタルの頭突きエンカウントの木到達不可が見つかりました。
LG2InvalidTileTreeNotFound = トレーナーIDと一致するクリスタルの頭突きエンカウントの木が見つかりませんでした。
LG2OTGender = クリスタル以外の2世代以前のポケモンは女性トレーナーは選択できません。
LG2TreeID = トレーナーIDと一致するクリスタルの頭突きエンカウントの木が見つかりました。
LG3EReader = 日本以外でカードeリーダーを使ったダークポケモン。未実装のエンカウント。
LG3OTGender = 「ポケモンコロシアム」「ポケモンXD」では女性トレーナーは選択できません
LG4InvalidTileR45Surf = 45ばんどうろ(4世代)の水上エンカウント。正規では到達不可能です。
LG5ID_N = Nの名前/表ID/裏IDが正しくありません。
LG5IVAll30 = Nのポケモンは個体値が全て30です。
LG5OTGenderN = Nのポケモンはトレーナーの性別が必ず男でなければなりません。
LG5PIDShinyGrotto = 隠し穴産のポケモンは色違いになりません。
LG5PIDShinyN = Nのポケモンは色違いは存在しません。
LG5SparkleInvalid = Nのポケモンフラグのチェックを外してください。
LG5SparkleRequired = Nのポケモンフラグのチェックを入れてください。
LGanbaruStatTooHigh = つ以上のがんばレベルが通常限界値10-個体値ボーナス)を超えています。
LGenderInvalidNone = 性別不明のポケモンは性別を持ちません。
LGeoBadOrder = 地域(おもいで):空白があります。
LGeoHardwareInvalid = 地域設定:この国は3DS地域設定にありません。
LGeoHardwareRange = 不正な地域
LGeoHardwareValid = 地域設定:この国は3DS地域設定にあります。
LGeoMemoryMissing = 地域設定(おもいで): おもいでがありません。
LGeoNoCountryHT = 地域設定(おもいで): トレーナー名が存在しますが、国の設定がされていません。
LGeoNoRegion = 地域設定(おもいで): 国設定なしに地域設定されています。
LHyperPerfectAll = 全ての個体値が31のためすごいとっくんはできません。
LHyperPerfectOne = 個体値31にはすごいとっくんはできません。
LHyperPerfectUnavailable = 現在の個体値ではもうすごいとっくんはできません。
LHyperTooLow_0 = すごいとっくんをするにはレベル{0}でなければなりません。
LItemEgg = タマゴはアイテムを持てません。
LItemUnreleased = この持ち物は解禁されていません。
LIVAllEqual_0 = 個体値は全て {0} です。
LIVF_COUNT0_31 = 少なくとも {0} つの個体値31が必要です。
LIVNotCorrect = 個体値がエンカウントタイプと一致しません。
LLevelEXPThreshold = 現在の経験値がレベルのしきい値と一致しています。
LLevelEXPTooHigh = 現在の経験値が100レベルの最大値を超えています。
LLevelMetBelow = 現在のレベルが出会ったレベルより低いです。
LLevelMetGift = ふしぎなおくりもので出会ったレベルと一致しません。
LLevelMetGiftFail = ふしぎなおくりもので出会ったレベルを下回っています。
LLevelMetSane = 出会った時のレベルより現在のレベルが下回っています。
LMarkValueOutOfRange_0 = Individual marking at index {0} is not within the allowed value range.
LMarkValueShouldBeZero = マーキングフラグが設定できません。
LMarkValueUnusedBitsPresent = マーキングフラグはアクセう可能な範囲を超えたビットを使用しています。
LMemoryArgBadCatch = {0} おもいで: {0} は捕獲できません。
LMemoryArgBadHatch = {0} おもいで: {0} は孵化できません。
LMemoryArgBadHT = おもいで: Can't have Handling Trainer Memory as Egg.
LMemoryArgBadID = {0} おもいで: Can't obtain Memory on {0} Version.
LMemoryArgBadItem = {0} おもいで: Species can't hold this item.
LMemoryArgBadLocation = {0} Memory: Can't obtain Location on {0} Version.
LMemoryArgBadMove = {0} Memory: Species can't learn this move.
LMemoryArgBadOTEgg = {0} Memory: Link Trade is not a valid first memory.
LMemoryArgBadSpecies = {0} Memory: Can't capture species in game.
LMemoryArgSpecies = {0} Memory: Species can be captured in game.
LMemoryCleared = Memory: Not cleared properly.
LMemoryF_0_Valid = {0} Memory is valid.
LMemoryFeelInvalid = {0} Memory: Invalid Feeling.
LMemoryHTFlagInvalid = Untraded: Current handler should not be the Handling Trainer.
LMemoryHTGender = HT Gender invalid: {0}
LMemoryHTLanguage = HT Language is missing.
LMemoryIndexArgHT = Should have a HT Memory TextVar value (somewhere).
LMemoryIndexFeel = {0} Memory: Feeling should be index {1}.
LMemoryIndexFeelHT09 = Should have a HT Memory Feeling value 0-9.
LMemoryIndexID = {0} Memory: Should be index {1}.
LMemoryIndexIntensity = {0} Memory: Intensity should be index {1}.
LMemoryIndexIntensityHT1 = Should have a HT Memory Intensity value (1st).
LMemoryIndexIntensityMin = {0} Memory: Intensity should be at least {1}.
LMemoryIndexLinkHT = Should have a Link Trade HT Memory.
LMemoryIndexVar = {0} Memory: TextVar should be index {1}.
LMemoryMissingHT = Memory: Handling Trainer Memory missing.
LMemoryMissingOT = Memory: Original Trainer Memory missing.
LMemorySocialTooHigh_0 = Social Stat should be <= {0}
LMemorySocialZero = Social Stat should be zero.
LMemoryStatAffectionHT0 = Untraded: Handling Trainer Affection should be 0.
LMemoryStatAffectionOT0 = OT Affection should be 0.
LMemoryStatEnjoyment = Enjoyment should be {0}.
LMemoryStatFriendshipHT0 = 未交換: 現在のトレーナーとのなつき度は0である必要があります。
LMemoryStatFriendshipOTBaseEvent = Event OT Friendship does not match base friendship.
LMemoryStatFullness = まんぷく度は {0} である必要があります。
LMetDetailTimeOfDay = 出会った時間が予想された範囲内にありません。
LMoveEggFIncompatible0_1 = {0} タマゴ技。 {1} のタマゴ技と両立できません。
LMoveEggIncompatible = タマゴ技。イベントによるタマゴ技と両立できません。
LMoveEggIncompatibleEvent = イベントによるタマゴ技。通常のタマゴ技と両立できません。
LMoveEggInherited = 遺伝可能なタマゴ技
LMoveEggInheritedTutor = 遺伝可能な教え技
LMoveEggInvalid = タマゴ技がありません。
LMoveEggInvalidEvent = タマゴ技。イベントによるタマゴではありません。
LMoveEggInvalidEventLevelUp = 遺伝可能なレベルアップ技。イベントによるタマゴではありません。
LMoveEggInvalidEventLevelUpGift = 遺伝可能なレベルアップ技。もらったタマゴではありません。
LMoveEggInvalidEventTMHM = 遺伝可能なわざマシン/ひでんマシン技。イベントによるタマゴではありません。
LMoveEggInvalidEventTutor = 遺伝可能な教え技。イベントによるタマゴではありません。
LMoveEggLevelUp = 遺伝可能なレベルアップ技
LMoveEggMissing = イベントによるタマゴ技がありません。
LMoveEggMoveGift = タマゴ技。もらったタマゴではありません。
LMoveEggTMHM = 遺伝可能なわざマシン/ひでんマシン技。
LMoveEventEggLevelUp = 遺伝可能なレベルアップ技。イベントによるタマゴ技と両立できません。
LMoveEvoFCombination_0 = 技の組み合わせは {0} 進化と両立できません。
LMoveEvoFHigher = 両立できない進化技。 {1} の技は他の {0} の技よりも高いレベルで習得します。
LMoveEvoFLower = 両立できない進化技。 {0} の技は他の {1} の技よりも低いレベルで習得します。
LMoveFDefault_0 = {0} 世代の通常技。
LMoveFExpect_0 = 次のような技が予想されます: {0}
LMoveFExpectSingle_0 = 予想: {0}
LMoveFLevelUp_0 = {0} 世代のレベルアップ技です。
LMoveFTMHM_0 = {0} 世代のわざマシン/ひでんマシン技です。
LMoveFTutor_0 = {0} 世代の教え技です。
LMoveKeldeoMismatch = ケルディオの技/フォルムが一致しません。
LMoveNincada = テッカニンの技は1つだけ覚えることが可能です。
LMoveNincadaEvo = テッカニンに進化させる際に、覚えられます。
LMoveNincadaEvoF_0 = {0} 世代でテッカニンに進化させる際、覚えられます。
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = 技 {0} のPPが上限を超えています。
LMovePPUpsTooHigh_0 = 技 {0} のポイントアップ上限を超えています。
LMoveRelearnDexNav = ずかんナビによる技ではありません。
LMoveRelearnEgg = ベースのタマゴ技
LMoveRelearnEggMissing = ベースのタマゴ技を設定してください
LMoveRelearnFExpect_0 = 次の技のいずれかを思い出し技に設定してください: {0} ({1})
LMoveRelearnFMiss_0 = 思い出し技がありません: {0}
LMoveRelearnInvalid = 思い出し可能な技がありません。
LMoveRelearnNone = 思い出し技が設定されていません。
LMoveRelearnUnderground = 地下大洞窟のタマゴ技がありません。
LMoveShopAlphaMoveShouldBeMastered = オヤブン技は皆伝マークがなければなりません。
LMoveShopAlphaMoveShouldBeOther = このオヤブン技では、オヤブンのエンカウントを調べることができません。
LMoveShopAlphaMoveShouldBeZero = オヤブンのみがオヤブン技を持つことが出来ます。
LMoveShopMasterInvalid_0 = {0} は手動で皆伝できません: 皆伝することはできません。
LMoveShopMasterNotLearned_0 = {0} は手動で皆伝できません: レベルアップで習得可能な技はありません。
LMoveShopPurchaseInvalid_0 = 技教えから {0} を習得できません。
LMoveSourceDefault = 通常技
LMoveSourceDuplicate = 重複した技
LMoveSourceEgg = タマゴ技
LMoveSourceEggEvent = イベントによるタマゴ技
LMoveSourceEmpty = 技が設定されていません。
LMoveSourceInvalid = この技は習得できません。
LMoveSourceInvalidSketch = この技は習得できません(スケッチ)。
LMoveSourceLevelUp = レベルアップ技
LMoveSourceRelearn = 思い出し技
LMoveSourceShared = 思い出しできない技
LMoveSourceSharedF = {0} 世代の思い出しできない技
LMoveSourceSpecial = 思い出しできない特別な技
LMoveSourceTMHM = わざマシン/ひでんマシンで習得した。
LMoveSourceTR = 想定外のわざレコードフラグ: {0}
LMoveSourceTutor = 技教えで習得した。
LNickFlagEggNo = タマゴにニックネームは付けられません。
LNickFlagEggYes = タマゴにニックネームは付ける必要があります。
LNickInvalidChar = このニックネームは付けられません。
LNickLengthLong = ニックネーム文字数が超過しています。
LNickLengthShort = ニックネームが空白です。
LNickMatchLanguage = 名前が種族名と一致します。
LNickMatchLanguageEgg = 名前が『タマゴ』です。
LNickMatchLanguageEggFail = 名前が『タマゴ』ではありません。
LNickMatchLanguageFail = ニックネームが種族名と一致しません。
LNickMatchLanguageFlag = ニックネームフラグが立ち、種族名と一致します。
LNickMatchNoOthers = ニックネームが別のポケモン名と一致しません。
LNickMatchNoOthersFail = ニックネームは別のポケモンの名前(+言語)と一致します。
LOT_IDEqual = 表IDと裏IDが同じです。
LOT_IDInvalid = その表IDと裏ID組み合わせは不正です。
LOT_IDs0 = 表IDと裏IDが0です。
LOT_SID0 = 裏IDが0です。
LOT_SID0Invalid = 裏IDは「00000」でなければなりません。
LOT_TID0 = 表IDが0です。
LOTLanguage = 言語IDは {1} ではなく、 {0} である必要があります。
LOTLong = トレーナー名の文字数が超過しています。
LOTShort = トレーナー名が空白です。
LOTSuspicious = 疑わしいトレーナーの詳細です。
LPIDEncryptWurmple = ケムッソの進化による暗号化定数が不一致です。
LPIDEncryptZero = 暗号化定数が設定されていません。
LPIDEqualsEC = 暗号化定数と性格値が同じです。
LPIDGenderMatch = 性別と性格値が一致しています。
LPIDGenderMismatch = 性別と性格値が一致しません。
LPIDNatureMatch = 性格と性格値は一致しています。
LPIDNatureMismatch = 性格と性格値が一致しません。
LPIDTypeMismatch = エンカウントタイプと性格値が一致しません。
LPIDZero = 性格値が設定されていません。
LPokerusDaysTooHigh_0 = ポケルスの残り日数が多すぎます; 範囲 <= {0}.
LPokerusStrainUnobtainable_0 = ポケルス株 {0} は取得できません。
LRibbonAllValid = 全てのリボンからなっている
LRibbonEgg = タマゴにリボンは設定できません。
LRibbonFInvalid_0 = 無効なリボンが設定されています:
LRibbonFMissing_0 = 次のリボンが不足しています:
LRibbonMarkingAffixedF_0 = 無効なリボン/マーキングが設定されています: {0}
LRibbonMarkingFInvalid_0 = 無効なマーキング: {0}
LStatAlphaInvalid = オヤブンフラグ不一致。
LStatBattleVersionInvalid = バトルバージョンは予想の範囲内ではありません。
LStatDynamaxInvalid = ダイマックスレベルが範囲外です。
LStatGigantamaxInvalid = キョダイマックスフラグの不一致。
LStatGigantamaxValid = ダイスープによってキョダイマックスフラグが変更されました。
LStatIncorrectCP = 計算されたCPが保存値と一致しません。
LStatIncorrectHeight = 計算された高さが保存値と一致しません。
LStatIncorrectHeightCopy = コピーした高さが元の高さと一致しません。
LStatIncorrectHeightValue = 高さが範囲と一致しません。
LStatIncorrectWeight = 計算された重さが保存値と一致しません。
LStatIncorrectWeightValue = 重さが範囲と一致しません。
LStatInvalidHeightWeight = 高さ/重さの数値が可能範囲を超えています。
LStatNatureInvalid = ミント性格補正が予想の範囲内にありません。
LStatNobleInvalid = キング/クイーンのフラグが不一致。
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = スパトレのクリアフラグが矛盾しています。
LSuperDistro = 配信限定スパトレはリリースされていません。
LSuperEgg = タマゴはスパトレができません。
LSuperNoComplete = Can't have active Super Training complete flag for origins.
LSuperNoUnlocked = Can't have active Super Training unlocked flag for origins.
LSuperUnavailable = Super Training missions are not available in games visited.
LSuperUnused = 未使用のスパトレにフラグが立っています。
LTeraTypeIncorrect = テラスタルタイプが一致しません。
LTeraTypeMismatch = テラスタルタイプが元のタイプのいずれにも一致しません。
LTradeNotAvailable = Encounter cannot be traded to the active trainer.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = VCからポケモンを入手できません。
LTransferCurrentHandlerInvalid = 不正なトレーナーの値です。トレーナー情報に他の値を入力してください。
LTransferEgg = 世代間でタマゴを送ることはできません。
LTransferEggLocationTransporter = 出会った場所が不正です。世代を超えてポケモンを送る必要があります。
LTransferEggMetLevel = 送られてきたポケモンの出会ったレベルが不正です。
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = 不正にフラグが立てられています。(バグの悪用)
LTransferHTFlagRequired = 現在の取り扱いトレーナーは元のトレーナーと同じであってはなりません。
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = 先のトレーナーと予想されるトレーナーの言語が一致しません。
LTransferHTMismatchName = 先のトレーナーと予想されるトレーナー名が一致しません。
LTransferMet = 出会った場所が不正です。原因はポケシフターかクラウンポケモンだと思われます。
LTransferMetLocation = 転送後の出会った場所が不正です。
LTransferMove = 転送して両立できない技です。
LTransferMoveG4HM = きりばらいかうずしおのどちらかを5世代に送る前に忘れさせてください。
LTransferMoveHM = {0} 世代のひでんマシンを覚えたポケモンは {1} 世代に送るために忘れさせなければなりません。
LTransferNature = 転送されたポケモンには不正な性格です。
LTransferNotPossible = 元のフォーマットから現在のフォーマットに転送できません。
LTransferObedienceLevel = 不正な従順レベルです。
LTransferOriginFInvalid0_1 = {0} は現在ロードされている ({1}) セーブファイルに存在できません。
LTransferPIDECBitFlip = 性格値は暗号化定数と(上位ビットを反転して)同じにする必要があります。
LTransferPIDECEquals = 性格値は暗号化定数と同じにする必要があります。
LTransferPIDECXor = 暗号化定数と色違い性格値が一致します。
LTransferTrackerMissing = HOME Trackerが見つかりません。
LTransferTrackerShouldBeZero = HOME Trackerをにしてください。
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = 내부 오류입니다.
L_ALegal = 존재 가능합니다!
L_AnalysisUnavailable = 이 포켓몬을 분석할 수 없습니다.
L_AValid = 사용 가능합니다.
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0} 기술 {1}: {2}
L_F0_RM_1_2 = {0} 떠올리기 기술 {1}: {2}
L_FEncounterType_0 = 인카운터 유형: {0}
L_FOriginSeed_0 = Origin Seed: {0}
L_FPIDType_0 = PID 유형: {0}
L_SFishy = 의심
L_SInvalid = 사용 불가능
L_SNotImplemented = 미구현
L_SValid = 사용 가능
L_XEnigmaBerry_0 = {0}열매
L_XHT = 소유했던 트레이너 (HT)
L_XKorean = 한국어 버전 포켓몬
L_XKoreanNon = 한국어 버전이 아닌 포켓몬
L_XLocation = Location
L_XMatches0_1 = 일치: {0} {1}
L_XNickname = Nickname
L_XOT = 어버이 (OT)
L_XRareFormEvo_0_1 = Evolves into form: {0} (rare: {1})
L_XWurmpleEvo_0 = 개무소 진화: {0}
LAbilityCapsuleUsed = 특성캡슐로 바뀐 특성입니다.
LAbilityFlag = 특성이 특성 번호와 일치합니다.
LAbilityHiddenFail = 숨겨진 특성이 인카운터 유형과 일치하지 않습니다.
LAbilityHiddenUnavailable = 숨겨진 특성을 사용할 수 없습니다.
LAbilityMismatch = 특성이 인카운터와 일치하지 않습니다.
LAbilityMismatch3 = 특성이 3세대 포켓몬 종류의 특성과 일치하지 않습니다.
LAbilityMismatchFlag = 특성이 특성 번호와 일치하지 않습니다.
LAbilityMismatchGift = 특성이 이상한소포와 일치하지 않습니다.
LAbilityMismatchGrotto = 은혈에서 포획한 포켓몬은 숨겨진 특성을 가지고 있어야 합니다.
LAbilityMismatchHordeSafari = 프렌드사파리/무리배틀이 아닌 야생 인카운터에서 숨겨진 특성이 설정되었습니다.
LAbilityMismatchPID = 특성이 PID와 일치하지 않습니다.
LAbilityMismatchSOS = 난입배틀이 아닌 야생 인카운터에서 숨겨진 특성이 설정되었습니다.
LAbilityPatchRevertUsed = Ability available with Ability Patch Revert.
LAbilityPatchUsed = Ability modified with Ability Patch.
LAbilityUnexpected = 포켓몬 종류/폼에서 사용할 수 없는 특성입니다.
LAwakenedCap = 각 AV는 {0}보다 클 수 없습니다.
LAwakenedShouldBeValue = 각 AV는 {0}보다 커야 합니다 ({1}).
LBallAbility = 숨겨진 특성을 잡을 수 없는 볼입니다.
LBallEggCherish = 일반 알은 프레셔스볼에 들어있을 수 없습니다.
LBallEggMaster = 일반 알은 마스터볼에 들어있을 수 없습니다.
LBallEnc = 인카운터 유형에 맞는 볼입니다.
LBallEncMismatch = 인카운터 유형에 맞지 않는 볼입니다.
LBallHeavy = 헤비볼로 가볍고 포획률이 낮은 포켓몬 종류를 잡을 수 없습니다 (7세대).
LBallNone = 만족한 체크가 없습니다. 존재 불가능한 포켓몬으로 가정합니다.
LBallSpecies = 이 포켓몬 종류를 잡을 수 없는 볼입니다.
LBallSpeciesPass = 이 포켓몬 종류를 잡을 수 있는 볼입니다.
LBallUnavailable = 만난 게임에서 얻을 수 없는 볼입니다.
LContestSheenTooHigh_0 = Contest Stat Sheen should be <= {0}.
LContestSheenTooLow_0 = Contest Stat Sheen should be >= {0}.
LContestZero = 컨디션은 0이어야 합니다.
LContestZeroSheen = Contest Stat Sheen should be 0.
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = Met Date is outside of distribution window.
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = EV가 2 남았습니다.
LEffortAbove252 = EV는 252 이하여야 합니다.
LEffortAbove510 = EV의 총합은 510 이하여야 합니다.
LEffortAllEqual = 모든 EV가 동일합니다.
LEffortCap100 = 4세대에서 레벨 100 인카운터의 각 EV는 100을 초과할 수 없습니다.
LEffortEgg = 알은 EV를 얻을 수 없습니다.
LEffortEXPIncreased = 현재 레벨이 만난 레벨 이상이지만 모든 EV가 0입니다.
LEffortShouldBeZero = EV를 얻을 수 없습니다.
LEffortUntrainedCap = 경험치를 수정하지 않은 채 변경한 EV는 {0}보다 클 수 없습니다.
LEggContest = 알은 컨디션을 올릴 수 없습니다.
LEggEXP = 알은 경험치를 얻을 수 없습니다.
LEggFMetLevel_0 = 만난 레벨이 잘못되었습니다. {0}으로 예상됩니다.
LEggHatchCycles = 사용할 수 없는 알 부화 사이클입니다.
LEggLocation = 만난 장소에서 알을 부화시킬 수 있습니다.
LEggLocationInvalid = 만난 장소에서 알을 부화시킬 수 없습니다.
LEggLocationNone = 알을 만난 장소가 잘못되었습니다. 없음으로 예상됩니다.
LEggLocationPalPark = 만난 장소가 잘못되었습니다. 팔파크로 예상됩니다.
LEggLocationTrade = 만난 장소에서 교환한 알을 부화시킬 수 있습니다.
LEggLocationTradeFail = 알을 만난 장소가 잘못되었습니다. 부화 전 알을 교환할 수 없습니다.
LEggMetLocationFail = 알을 만난 장소에서 알을 얻을 수 없습니다.
LEggNature = 알은 성격과 능력치 성격이 서로 다를 수 없습니다.
LEggPokeathlon = 알은 포켓슬론 능력치를 가질 수 없습니다.
LEggPokerus = 알은 포켓러스에 감염될 수 없습니다.
LEggPP = 알은 PP를 수정할 수 없습니다.
LEggPPUp = 알에는 PP업을 적용할 수 없습니다.
LEggRelearnFlags = 떠올리기 기술 플래그가 없어야 합니다.
LEggShinyLeaf = 알은 빛나는나뭇잎/왕관을 가질 수 없습니다.
LEggShinyPokeStar = 알은 포켓우드 스타가 될 수 없습니다.
LEggSpecies = 이 포켓몬 종류의 알은 얻을 수 없습니다.
LEggUnhatched = 사용할 수 있는 부화 전 알입니다.
LEncCondition = 장소에서 사용할 수 있는 야생 인카운터입니다.
LEncConditionBadRNGFrame = 가능한 RNG 프레임과 인카운터 조건이 일치하지 않습니다.
LEncConditionBadSpecies = 만난 게임에 존재하지 않는 포켓몬 종류입니다.
LEncConditionBlack = 장소에서 사용할 수 있는 야생 인카운터입니다 (검정비드로).
LEncConditionBlackLead = 장소에서 사용할 수 있는 야생 인카운터입니다 (검정비드로 & 프레셔/의욕/의기양양).
LEncConditionDexNav = 장소에서 사용할 수 있는 야생 인카운터입니다 (도감 내비).
LEncConditionLead = 장소에서 사용할 수 있는 야생 인카운터입니다 (프레셔/의욕/의기양양).
LEncConditionWhite = 장소에서 사용할 수 있는 야생 인카운터입니다 (하양비드로).
LEncConditionWhiteLead = 장소에서 사용할 수 있는 야생 인카운터입니다 (하양비드로 & 프레셔/의욕/의기양양).
LEncGift = 만난 게임의 선물받은 알 인카운터와 일치하지 않습니다.
LEncGiftEggEvent = 만난 게임의 이벤트 알 인카운터와 일치하지 않습니다.
LEncGiftIVMismatch = IV가 이상한소포 데이터와 일치하지 않습니다.
LEncGiftNicknamed = 이벤트 선물의 이름 플래그가 켜져 있습니다.
LEncGiftNotFound = 이상한소포 데이터베이스에 존재하지 않습니다.
LEncGiftPIDMismatch = 이상한소포의 고정된 PID가 일치하지 않습니다.
LEncGiftShinyMismatch = 이상한소포의 색이 다른 포켓몬 여부가 일치하지 않습니다.
LEncGiftVersionNotDistributed = 이 버전에서 받을 수 없는 이상한소포입니다.
LEncInvalid = 만난 게임의 인카운터와 일치하지 않습니다.
LEncMasteryInitial = Initial move mastery flags do not match the encounter's expected state.
LEncStaticMatch = 사용 가능한 선물/고정된 인카운터입니다.
LEncStaticPIDShiny = 고정된 인카운터의 색이 다른 포켓몬 여부가 일치하지 않습니다.
LEncStaticRelearn = 고정된 인카운터의 떠올리기 기술이 일치하지 않습니다.
LEncTradeChangedNickname = 게임 내 교환의 이름이 달라졌습니다.
LEncTradeChangedOT = 게임 내 교환의 어버이가 달라졌습니다.
LEncTradeIndexBad = 게임 내 교환의 인덱스가 잘못되었을 수 있습니다.
LEncTradeMatch = 사용 가능한 게임 내 교환입니다.
LEncTradeUnchanged = 게임 내 교환의 어버이와 이름이 달라졌습니다.
LEncTypeMatch = 인카운터 유형과 인카운터가 일치합니다.
LEncTypeMismatch = 인카운터 유형과 인카운터가 일치하지 않습니다.
LEncUnreleased = 배포되지 않은 이벤트입니다.
LEncUnreleasedEMewJP = 일본산이 아닌 뮤는 머나먼 고도에서 포획할 수 없습니다. 배포되지 않은 이벤트입니다.
LEncUnreleasedHoOArceus = 아르세우스는 시작의 방에서 포획할 수 없습니다. 배포되지 않은 이벤트입니다.
LEncUnreleasedPtDarkrai = Pt가 아닌 버전에서는 신월섬에서 다크라이를 잡을 수 없습니다. 배포되지 않은 이벤트입니다.
LEncUnreleasedPtShaymin = Pt가 아닌 버전에서는 꽃의 낙원에서 쉐이미를 잡을 수 없습니다. 배포되지 않은 이벤트입니다.
LEReaderAmerica = 일본 세이브게임에서 북미 E-Reader 열매가 설정되었습니다.
LEReaderInvalid = 사용할 수 없는 E-Reader 열매입니다.
LEReaderJapan = 국제 세이브게임에서 일본 E-Reader 열매가 설정되었습니다.
LEvoInvalid = 사용할 수 없는 진화입니다 (또는 레벨/통신진화를 만족하지 않습니다).
LEvoTradeReq = 게임 내에서 교환한 {0} 포켓몬은 {1}(으)로 진화해야 합니다.
LEvoTradeReqOutsider = 동떨어진(Outsider) {0} 포켓몬은 {1}(으)로 진화해야 합니다.
LEvoTradeRequired = 버전에 따른 진화는 반대 버전으로의 교환이 필요하므로 소유했던 트레이너를 설정해야 합니다.
LFateful = 게임 내 특수한 운명적인 만남입니다.
LFatefulGiftMissing = 일치하는 인카운터 없이 운명적인 만남이 설정되었습니다.
LFatefulInvalid = 운명적인 만남이 켜져 있지 않아야 합니다.
LFatefulMissing = 게임 내 특수한 운명적인 만남 플래그가 켜져 있지 않습니다.
LFatefulMystery = 이상한소포에 운명적인 만남 플래그가 켜져 있습니다.
LFatefulMysteryMissing = 이상한소포에 운명적인 만남 플래그가 켜져 있지 않습니다.
LFavoriteMarkingUnavailable = 즐겨찾기 마킹을 할 수 없습니다.
LFormArgumentHigh = 현재 폼에 비해 폼 인수가 너무 높습니다.
LFormArgumentInvalid = Form argument is not valid.
LFormArgumentLow = 현재 폼에 비해 폼 인수가 너무 낮습니다.
LFormArgumentNotAllowed = 이 인카운터에는 폼 인수가 허용되지 않습니다.
LFormArgumentValid = 사용 가능한 폼 인수입니다.
LFormBattle = 배틀 밖에서 존재할 수 없는 폼입니다.
LFormEternal = 사용 가능한 영원의 꽃 인카운터입니다.
LFormEternalInvalid = 사용할 수 없는 영원의 꽃 인카운터입니다.
LFormInvalidExpect_0 = Form is invalid, expected form index {0}.
LFormInvalidGame = 이 양식은 원래 게임에서 얻을 수 없습니다.
LFormInvalidNature = Form cannot have this nature.
LFormInvalidRange = 폼 번호가 범위를 벗어났습니다. 예상되는 폼 번호는 최대 {0}입니다. got {1}.
LFormItem = 지닌 물건이 도구와 일치합니다.
LFormItemInvalid = 지닌 물건이 도구와 일치하지 않습니다.
LFormParty = 파티 밖에서 존재할 수 없는 폼입니다.
LFormPikachuCosplay = 옷갈아입기 피카츄만 가질 수 있는 폼입니다.
LFormPikachuCosplayInvalid = 옷갈아입기 피카츄는 기본 폼을 가질 수 없습니다.
LFormPikachuEventInvalid = 이벤트 피카츄는 기본 폼을 가질 수 없습니다.
LFormValid = 사용할 수 있는 폼입니다.
LFormVivillon = 사용 가능한 비비용 패턴입니다.
LFormVivillonEventPre = 진화 전에 이벤트 비비용 패턴이 설정되었습니다.
LFormVivillonInvalid = 사용할 수 없는 비비용 패턴입니다.
LFormVivillonNonNative = Non-native Vivillon pattern.
LG1CatchRateChain = 포획률이 포켓몬 진화 체인의 아무 포켓몬과도 일치하지 않습니다.
LG1CatchRateEvo = 포획률이 인카운터 없이 포켓몬 종류와 일치합니다. 진화 전에 포획한 포켓몬으로 예상됩니다.
LG1CatchRateItem = 포획률이 2세대의 유효한 지닌 물건과 일치하지 않습니다.
LG1CatchRateMatchPrevious = 포획률이 포켓몬 진화 체인의 아무 포켓몬과 일치합니다.
LG1CatchRateMatchTradeback = 포획률이 2세대의 유효한 지닌 물건과 일치합니다.
LG1CatchRateNone = 포획률이 포켓몬 진화 체인의 아무 포켓몬, 또는 2세대의 지닌 물건과 일치하지 않습니다.
LG1CharNick = 1/2세대에서 사용할 수 없는 문자가 포켓몬 이름에 포함되어 있습니다.
LG1CharOT = 1/2세대에서 사용할 수 없는 문자가 어버이 이름에 포함되어 있습니다.
LG1GBEncounter = 버추얼 콘솔 게임에서 얻을 수 없는 특수 인카운터입니다.
LG1MoveExclusive = 1세대 전용 기술입니다. 이전 세대로 옮길 수 없는 자력기와 함께 존재할 수 없습니다.
LG1MoveLearnSameLevel = 함께 존재할 수 없는 기술입니다. 레드/그린/옐로에서 같은 레벨에 배우는 기술입니다.
LG1MoveTradeback = 이전 세대로 옮길 수 없는 교배기입니다. 1세대 전용 기술과 함께 존재할 수 없습니다.
LG1OTEvent = RBY 이벤트의 어버이 이름이 다릅니다.
LG1OTGender = 1/2세대에서는 여성 어버이를 사용할 수 없습니다.
LG1Stadium = 스타디움 어버이가 잘못되었습니다.
LG1StadiumInternational = 유효한 국제판 스타디움 어버이입니다.
LG1StadiumJapanese = 유효한 일본판 스타디움 어버이입니다.
LG1TradebackPreEvoMove = 이전 세대로 옮길 수 없는 진화 전 기술입니다. 1세대 전용 기술과 함께 존재할 수 없습니다.
LG1Type1Fail = 사용할 수 없는 타입 A 값입니다. 포켓몬 종류 유형과 일치하지 않습니다.
LG1Type2Fail = 사용할 수 없는 타입 B 값입니다. 포켓몬 종류 유형과 일치하지 않습니다.
LG1TypeMatch1 = 유효한 타입 A 값입니다. 포켓몬 종류 유형과 일치합니다.
LG1TypeMatch2 = 유효한 타입 B 값입니다. 포켓몬 종류 유형과 일치합니다.
LG1TypeMatchPorygon = 유효한 타입 A 및 타입 B 값을 지닌 폴리곤입니다.
LG1TypePorygonFail = 사용할 수 없는 타입 A 및 타입 B 값을 지닌 폴리곤입니다. 유효한 타입 조합과 일치하지 않습니다.
LG1TypePorygonFail1 = 사용할 수 없는 타입 A 값을 지닌 폴리곤입니다.
LG1TypePorygonFail2 = 사용할 수 없는 타입 B 값을 지닌 폴리곤입니다.
LG2InvalidTilePark = 자연공원의 낚시 인카운터입니다. 물 타일에 접근할 수 없는 지역입니다.
LG2InvalidTileR14 = 관동 14번 도로의 낚시 인카운터입니다. 물 타일에 접근할 수 없는 지역입니다.
LG2InvalidTileSafari = 2세대 사파리존의 낚시 인카운터입니다. 접근할 수 없는 지역입니다.
LG2InvalidTileTreeID = 크리스탈 버전 어버이 ID와 일치하는 박치기 인카운터용 나무를 찾았습니다. 그러나 접근할 수 없는 나무입니다.
LG2InvalidTileTreeNotFound = 크리스탈 버전 어버이 ID와 일치하는 박치기 인카운터용 나무를 찾지 못했습니다.
LG2OTGender = OT from Virtual Console games other than Crystal cannot be female.
LG2TreeID = 크리스탈 버전 어버이 ID와 일치하는 박치기 인카운터용 나무를 찾았습니다.
LG3EReader = 일본판이 아닌 버전의 섀도우 E-reader 포켓몬입니다. 배포되지 않은 인카운터입니다.
LG3OTGender = 콜로세움/XD 버전에서는 여성 어버이를 사용할 수 없습니다.
LG4InvalidTileR45Surf = 성도 45번 도로는 물 타일에 접근할 수 없으므로 파도타기 인카운터가 불가능합니다.
LG5ID_N = N의 이름/TID16/SID16가 잘못되었습니다.
LG5IVAll30 = N이 소유한 포켓몬의 IV는 30이어야 합니다.
LG5OTGenderN = N's Pokémon must have a male OT gender.
LG5PIDShinyGrotto = 은혈에서 포획한 포켓몬은 색이 다를 수 없습니다.
LG5PIDShinyN = N이 소유한 포켓몬은 색이 다를 수 없습니다.
LG5SparkleInvalid = 게임 내 특수한 N 전용 반짝임 플래그가 켜져 있지 않아야 합니다.
LG5SparkleRequired = 게임 내 특수한 N 전용 반짝임 플래그가 켜져 있지 않습니다.
LGanbaruStatTooHigh = One or more Ganbaru Value is above the natural limit of (10 - IV bonus).
LGenderInvalidNone = 무성 포켓몬은 성별을 가질 수 없습니다.
LGeoBadOrder = 지오로케이션 기억: 빈 공간이 존재합니다.
LGeoHardwareInvalid = 지오로케이션: 국가가 3DS 지역 내에 있지 않습니다.
LGeoHardwareRange = 사용할 수 없는 3DS 지역입니다.
LGeoHardwareValid = 지오로케이션: 국가가 3DS 지역 내에 있습니다.
LGeoMemoryMissing = 지오로케이션 기억: 기억이 존재해야 합니다.
LGeoNoCountryHT = 지오로케이션 기억: 소유했던 트레이너의 이름이 존재하지만 이전 국가가 설정되어 있지 않습니다.
LGeoNoRegion = 지오로케이션 기억: 국가는 설정되어 있지만 지역이 설정되어 있지 않습니다.
LHyperPerfectAll = 모든 IV가 31인 포켓몬은 대단한 특훈을 받을 수 없습니다.
LHyperPerfectOne = IV 31은 대단한 특훈을 시킬 수 없습니다.
LHyperPerfectUnavailable = Can't Hyper Train any IV(s).
LHyperTooLow_0 = 레벨 {0} 미만인 포켓몬은 대단한 특훈을 받을 수 없습니다.
LItemEgg = 알은 물건을 지닐 수 없습니다.
LItemUnreleased = 지닌 물건이 배포되지 않은 물건입니다.
LIVAllEqual_0 = All IVs are {0}.
LIVF_COUNT0_31 = 최소 {0}가지의 IV가 31이어야 합니다.
LIVNotCorrect = IV가 인카운터 요구 조건과 일치하지 않습니다.
LLevelEXPThreshold = 현재 경험치가 레벨 한계와 일치합니다.
LLevelEXPTooHigh = Current experience exceeds maximum amount for level 100.
LLevelMetBelow = 현재 레벨이 만난 레벨보다 낮습니다.
LLevelMetGift = 만난 레벨이 이상한소포 레벨과 일치하지 않습니다.
LLevelMetGiftFail = 현재 레벨이 이상한소포 레벨보다 낮습니다.
LLevelMetSane = 현재 레벨이 만난 레벨보다 낮지 않습니다.
LMarkValueOutOfRange_0 = Individual marking at index {0} is not within the allowed value range.
LMarkValueShouldBeZero = Marking flags cannot be set.
LMarkValueUnusedBitsPresent = Marking flags uses bits beyond the accessible range.
LMemoryArgBadCatch = {0} 추억: {0}은(는) 이 포켓몬을 포획하지 않았습니다.
LMemoryArgBadHatch = {0} 추억: {0}은(는) 이 알을 부화시키지 않았습니다.
LMemoryArgBadHT = 추억: 알 상태에서 소유했던 트레이너와의 추억을 가질 수 없습니다.
LMemoryArgBadID = {0} 추억: {0} 버전에서 얻어올 수 없는 추억입니다.
LMemoryArgBadItem = {0} Memory: Species can't hold this item.
LMemoryArgBadLocation = {0} 추억: {0} 버전에서 얻어올 수 없는 장소입니다.
LMemoryArgBadMove = {0} 추억: 이 기술을 배울 수 없는 포켓몬 종류입니다.
LMemoryArgBadOTEgg = {0} 추억: 통신교환은 첫 번째 추억으로 사용할 수 없습니다.
LMemoryArgBadSpecies = {0} 추억: 이 버전에서 잡을 수 없는 포켓몬 종류입니다.
LMemoryArgSpecies = {0} 추억: 이 버전에서 잡을 수 있는 포켓몬 종류입니다.
LMemoryCleared = 추억: 제대로 지워지지 않았습니다.
LMemoryF_0_Valid = {0} 추억을 사용할 수 있습니다.
LMemoryFeelInvalid = {0} 추억: Invalid Feeling.
LMemoryHTFlagInvalid = 교환 경험 없음: 현재 소유자는 소유했던 트레이너가 될 수 없습니다.
LMemoryHTGender = 소유했던 트레이너의 성별이 잘못되었습니다: {0}
LMemoryHTLanguage = 소유했던 트레이너의 언어가 없습니다.
LMemoryIndexArgHT = 소유했던 트레이너와의 추억 중 TextVar 값을 가지고 있어야 합니다 (아무 곳이나).
LMemoryIndexFeel = {0} 추억: Feeling은 인덱스 {1}이어야 합니다.
LMemoryIndexFeelHT09 = 소유했던 트레이너와의 추억 중 Feeling 값을 가지고 있어야 합니다 (0-9).
LMemoryIndexID = {0} 추억: 인덱스 {1}이어야 합니다.
LMemoryIndexIntensity = {0} 추억: 강도는 인덱스 {1}이어야 합니다.
LMemoryIndexIntensityHT1 = 소유했던 트레이너와의 추억 중 강도 값을 가지고 있어야 합니다 (첫 번째).
LMemoryIndexIntensityMin = {0} 추억: 강도는 최소 {1}이어야 합니다.
LMemoryIndexLinkHT = 소유했던 통신교환 트레이너와의 추억을 가지고 있어야 합니다.
LMemoryIndexVar = {0} 추억: TextVar는 인덱스 {1}이어야 합니다.
LMemoryMissingHT = 추억: 소유했던 트레이너와의 추억이 없습니다.
LMemoryMissingOT = 추억: 어버이와의 추억이 없습니다.
LMemorySocialTooHigh_0 = Social Stat should be <= {0}
LMemorySocialZero = Social Stat should be zero.
LMemoryStatAffectionHT0 = 교환 경험 없음: 소유했던 트레이너와의 절친도는 0이어야 합니다.
LMemoryStatAffectionOT0 = 어버이와의 절친도는 0이어야 합니다.
LMemoryStatEnjoyment = Enjoyment should be {0}.
LMemoryStatFriendshipHT0 = 교환 경험 없음: 소유했던 트레이너와의 친밀도는 0이어야 합니다.
LMemoryStatFriendshipOTBaseEvent = 이벤트 어버이와의 친밀도가 기본 친밀도와 일치하지 않습니다.
LMemoryStatFullness = Fullness should be {0}.
LMetDetailTimeOfDay = Met Time of Day value is not within the expected range.
LMoveEggFIncompatible0_1 = 유전받은 {0} 기술입니다. 유전받은 {1} 기술과 함께 존재할 수 없습니다.
LMoveEggIncompatible = 교배기입니다. 이벤트 교배기와 함께 존재할 수 없습니다.
LMoveEggIncompatibleEvent = 이벤트 교배기입니다. 일반 교배기와 함께 존재할 수 없습니다.
LMoveEggInherited = 유전받은 교배기입니다.
LMoveEggInheritedTutor = 유전받은 기술 가르침 기술입니다.
LMoveEggInvalid = 예상된 교배기가 아닙니다.
LMoveEggInvalidEvent = 교배기입니다. 이벤트 알에서 예상되는 기술이 아닙니다.
LMoveEggInvalidEventLevelUp = 유전받은 레벨업 기술입니다. 이벤트 알에서 예상된 기술이 아닙니다.
LMoveEggInvalidEventLevelUpGift = 유전받은 레벨업 기술입니다. 이벤트 알에서 예상된 기술이 아닙니다.
LMoveEggInvalidEventTMHM = 우전받은 기술머신/비전머신 기술입니다. 이벤트 알에서 예상된 기술이 아닙니다.
LMoveEggInvalidEventTutor = 유전받은 기술 가르침 기술입니다. 이벤트 알에서 예상된 기술이 아닙니다.
LMoveEggLevelUp = 유전받은 레벨업 기술입니다.
LMoveEggMissing = 이벤트 교배기가 없습니다.
LMoveEggMoveGift = 교배기입니다. 이벤트 알에서 예상된 기술이 아닙니다.
LMoveEggTMHM = 유전받은 기술머신/비전머신 기술입니다.
LMoveEventEggLevelUp = 유전받은 레벨업 기술입니다. 이벤트 교배기와 함께 존재할 수 없습니다.
LMoveEvoFCombination_0 = 기술 조합이 {0} 진화와 호환되지 않습니다.
LMoveEvoFHigher = 함께 존재할 수 없는 기술입니다. {1}은(는) {0}보다 높은 레벨에 배우는 기술입니다.
LMoveEvoFLower = 함께 존재할 수 없는 기술입니다. {0}은(는) {1}보다 낮은 레벨애 배우는 기술입니다.
LMoveFDefault_0 = {0}세대 기본 기술입니다.
LMoveFExpect_0 = 다음 기술이 예상됩니다: {0}
LMoveFExpectSingle_0 = Expected: {0}
LMoveFLevelUp_0 = {0}세대 레벨업 기술입니다.
LMoveFTMHM_0 = {0}세대 기술머신/비전머신 기술입니다.
LMoveFTutor_0 = {0}세대 기술 가르침 기술입니다.
LMoveKeldeoMismatch = 케르디오의 기술과 폼이 일치하지 않습니다.
LMoveNincada = 하나의 아이스크 기술만 가질 수 있습니다.
LMoveNincadaEvo = 토중몬에서 아이스크로 진화하면서 배운 기술입니다.
LMoveNincadaEvoF_0 = {0}세대에서 토중몬에서 아이스크로 진화하면서 배운 기술입니다.
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = 기술 {0}의 PP가 허용된 값보다 많습니다.
LMovePPUpsTooHigh_0 = Move {0} PP Ups is above the amount allowed.
LMoveRelearnDexNav = 도감 내비 기술이 예상과 다릅니다.
LMoveRelearnEgg = 베이스 자력기입니다.
LMoveRelearnEggMissing = 베이스 자력기가 없습니다.
LMoveRelearnFExpect_0 = 다음 떠올리기 기술이 예상됩니다: {0} ({1})
LMoveRelearnFMiss_0 = 떠올리기 기술이 없습니다: {0}
LMoveRelearnInvalid = 떠올리기 기술이 예상과 다릅니다.
LMoveRelearnNone = 슬롯에 떠올리기 기술이 없어야 할 것으로 예상됩니다.
LMoveRelearnUnderground = Not an expected Underground egg move.
LMoveShopAlphaMoveShouldBeMastered = Alpha Move should be marked as mastered.
LMoveShopAlphaMoveShouldBeOther = Alpha encounter cannot be found with this Alpha Move.
LMoveShopAlphaMoveShouldBeZero = Only Alphas may have an Alpha Move set.
LMoveShopMasterInvalid_0 = Cannot manually master {0}: not permitted to master.
LMoveShopMasterNotLearned_0 = Cannot manually master {0}: not in possible learned level up moves.
LMoveShopPurchaseInvalid_0 = Cannot purchase {0} from the move shop.
LMoveSourceDefault = 기본 기술입니다.
LMoveSourceDuplicate = 중복되는 기술입니다.
LMoveSourceEgg = 자력기입니다.
LMoveSourceEggEvent = 이벤트 자력기입니다.
LMoveSourceEmpty = 비어 있는 기술입니다.
LMoveSourceInvalid = 사용할 수 없는 기술입니다.
LMoveSourceInvalidSketch = 사용할 수 없는 기술입니다 (스케치).
LMoveSourceLevelUp = 레벨업 기술입니다.
LMoveSourceRelearn = 떠올리기 기술입니다.
LMoveSourceShared = Shared Non-Relearn Move.
LMoveSourceSharedF = Shared Non-Relearn Move in Generation {0}.
LMoveSourceSpecial = 다시 배울 수 없는 특별한 기술입니다.
LMoveSourceTMHM = 기술머신/비전머신 기술입니다.
LMoveSourceTR = Unexpected Technical Record Learned flag: {0}
LMoveSourceTutor = 기술 가르침 기술입니다.
LNickFlagEggNo = 알은 반드시 이름 플래그가 꺼져 있어야 합니다.
LNickFlagEggYes = 알은 반드시 이름 플래그가 켜져 있어야 합니다.
LNickInvalidChar = 이 이름은 사용할 수 없습니다.
LNickLengthLong = 이름이 너무 깁니다.
LNickLengthShort = 이름이 비어 있습니다.
LNickMatchLanguage = 이름이 포켓몬 종류와 일치합니다.
LNickMatchLanguageEgg = 알이 나라별 알 이름과 일치합니다.
LNickMatchLanguageEggFail = 알 이름이 언어별 알 이름과 일치하지 않습니다.
LNickMatchLanguageFail = 이름이 포켓몬 종류와 일치하지 않습니다.
LNickMatchLanguageFlag = 이름 플래그가 켜져 있으나 이름이 포켓몬 종류와 일치합니다.
LNickMatchNoOthers = 이름이 다른 포켓몬 종류와 일치하지 않습니다.
LNickMatchNoOthersFail = 이름이 다른 포켓몬 종류와 일치합니다 (+언어).
LOT_IDEqual = TID16와 SID16가 동일합니다.
LOT_IDInvalid = TID and SID combination is not possible.
LOT_IDs0 = TID16와 SID16가 0입니다.
LOT_SID0 = SID16가 0입니다.
LOT_SID0Invalid = SID16는 0이어야 합니다.
LOT_TID0 = TID16가 0입니다.
LOTLanguage = 언어 ID는 {1}이 아니라 {0}이어야 합니다.
LOTLong = 어버이 이름이 너무 깁니다.
LOTShort = 어버이의 이름이 너무 짧습니다.
LOTSuspicious = 의심을 받을 수 있는 어버이입니다.
LPIDEncryptWurmple = 개무소의 진화 형태가 암호화 상수와 일치하지 않습니다.
LPIDEncryptZero = 암호화 상수가 설정되어 있지 않습니다.
LPIDEqualsEC = 암호화 상수가 PID와 일치합니다.
LPIDGenderMatch = PID와 성별이 일치합니다.
LPIDGenderMismatch = PID와 성별이 일치하지 않습니다.
LPIDNatureMatch = PID와 성격이 일치합니다.
LPIDNatureMismatch = PID와 성격이 일치하지 않습니다.
LPIDTypeMismatch = 인카운터 유형 PID가 일치하지 않습니다.
LPIDZero = PID가 지정되지 않았습니다.
LPokerusDaysTooHigh_0 = Pokérus Days Remaining value is too high; expected <= {0}.
LPokerusStrainUnobtainable_0 = Pokérus Strain {0} cannot be obtained.
LRibbonAllValid = 모든 리본이 채워졌습니다.
LRibbonEgg = 알은 리본을 얻을 수 없습니다.
LRibbonFInvalid_0 = 사용할 수 없는 리본:
LRibbonFMissing_0 = 없는 리본:
LRibbonMarkingAffixedF_0 = Invalid Affixed Ribbon/Marking: {0}
LRibbonMarkingFInvalid_0 = Invalid Marking: {0}
LStatAlphaInvalid = Alpha Flag mismatch.
LStatBattleVersionInvalid = Battle Version is not within the expected range.
LStatDynamaxInvalid = 다이맥스 레벨이 예상 범위를 벗어났습니다.
LStatGigantamaxInvalid = 거다이맥스 플래그가 일치하지 않습니다.
LStatGigantamaxValid = Gigantamax Flag was changed via Max Soup.
LStatIncorrectCP = 계산된 CP와 저장된 값이 일치하지 않습니다.
LStatIncorrectHeight = 계산된 키와 저장된 값이 일치하지 않습니다.
LStatIncorrectHeightCopy = Copy Height does not match the original value.
LStatIncorrectHeightValue = Height does not match the expected value.
LStatIncorrectWeight = 계산된 몸무게와 저장된 값이 일치하지 않습니다.
LStatIncorrectWeightValue = Weight does not match the expected value.
LStatInvalidHeightWeight = Height / Weight values are statistically improbable.
LStatNatureInvalid = Stat Nature is not within the expected range.
LStatNobleInvalid = Noble Flag mismatch.
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = 대단한 특훈 완료 플래그가 일치하지 않습니다.
LSuperDistro = 배분한 대단한 특훈 미션이 배포되지 않은 미션입니다.
LSuperEgg = 알은 대단한 특훈을 시킬 수 없습니다.
LSuperNoComplete = 만난 게임에서 대단한 특훈 완료 플래그를 켤 수 없습니다.
LSuperNoUnlocked = 만난 게임에서 대단한 특훈 해금 플래그를 켤 수 없습니다.
LSuperUnavailable = 방문했던 게임에서 대단한 특훈 미션을 사용할 수 없습니다.
LSuperUnused = 사용되지 않는 대단한 특훈 플래그가 켜져 있습니다.
LTeraTypeIncorrect = Tera Type does not match the expected value.
LTeraTypeMismatch = Tera Type does not match either of the default types.
LTradeNotAvailable = Encounter cannot be traded to the active trainer.
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = 버추얼 콘솔 게임에서 얻을 수 없는 포켓몬 종류입니다.
LTransferCurrentHandlerInvalid = Invalid Current handler value, trainer details for save file expected another value.
LTransferEgg = 알은 세대를 옮길 수 없습니다.
LTransferEggLocationTransporter = 만난 장소가 잘못되었습니다. 포케시프터로 예상됩니다.
LTransferEggMetLevel = 만난 장소가 잘못되었습니다.
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = Flagged as illegal by the game (glitch abuse).
LTransferHTFlagRequired = 현재의 핸들링 트레이너는 원래의 트레이너가 될 수 없습니다.
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = Handling trainer does not match the expected trainer language.
LTransferHTMismatchName = Handling trainer does not match the expected trainer name.
LTransferMet = 만난 장소가 잘못되었습니다. 포케시프터 또는 크라운시티로 예상됩니다.
LTransferMetLocation = 옮겨진 만난 장소가 잘못되었습니다.
LTransferMove = 호환되지 않는 전송 공격.
LTransferMoveG4HM = 안개제거와 바다회오리가 함께 존재합니다. 둘 중 하나는 5세대로 옮기기 전에 제거해야 합니다.
LTransferMoveHM = {0}세대 비전머신입니다. {1}세대로 옮기기 전에 제거해야 합니다.
LTransferNature = Invalid Nature for transfer Experience.
LTransferNotPossible = Unable to transfer into current format from origin format.
LTransferObedienceLevel = Invalid Obedience Level.
LTransferOriginFInvalid0_1 = 현재 로드한 세이브파일 ({1}) 에서는 {0} 버전에서 만난 포켓몬이 존재할 수 없습니다.
LTransferPIDECBitFlip = PID는 Top bit가 뒤집힌 암호화 상수와 동일해야 합니다!
LTransferPIDECEquals = PID는 암호화 상수와 동일해야 합니다!
LTransferPIDECXor = 암호화 상수가 색이 다르도록 계산된 PID와 일치합니다.
LTransferTrackerMissing = Pokémon HOME Transfer Tracker is missing.
LTransferTrackerShouldBeZero = Pokémon HOME Transfer Tracker should be 0.
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

View File

@ -1,423 +0,0 @@
L_AError = 内部错误。
L_ALegal = 合法。
L_AnalysisUnavailable = 无法分析该宝可梦。
L_AValid = 有效。
L_F0_1 = {0} {1}
L_F0_M_1_2 = {0}招式 {1} {2}
L_F0_RM_1_2 = {0}回忆招式 {1} {2}
L_FEncounterType_0 = 相遇方式: {0}
L_FOriginSeed_0 = 原始Seed {0}
L_FPIDType_0 = PID类型 {0}
L_SFishy = 可疑
L_SInvalid = 非法
L_SNotImplemented = 功能未实现
L_SValid = 合法
L_XEnigmaBerry_0 = {0}果
L_XHT = 持有人
L_XKorean = 韩版
L_XKoreanNon = 非韩版
L_XLocation = 相遇地点
L_XMatches0_1 = 匹配: {0} {1}
L_XNickname = 宝可梦昵称
L_XOT = 初训家
L_XRareFormEvo_0_1 = 进化为「{0}」形态(该可宝梦种类的「{1}」形态更为稀有)
L_XWurmpleEvo_0 = 刺尾虫进化形态: {0}
LAbilityCapsuleUsed = 特性被特性胶囊改变。
LAbilityFlag = 特性与特性序号一致。
LAbilityHiddenFail = 隐藏特性与相遇方式不一致。
LAbilityHiddenUnavailable = 隐藏特性不可获得。
LAbilityMismatch = 特性与相遇方式不一致。
LAbilityMismatch3 = 特性与三代种类特性不一致。
LAbilityMismatchFlag = 特性与特性值不一致。
LAbilityMismatchGift = 特性与神秘礼物不一致。
LAbilityMismatchGrotto = 隐藏洞穴捕获的宝可梦必定为隐藏特性。
LAbilityMismatchHordeSafari = 非群战/朋友原野区获得隐藏特性。
LAbilityMismatchPID = 特性与PID不一致。
LAbilityMismatchSOS = 非帮手宝可梦拥有隐藏特性。
LAbilityPatchRevertUsed = 特性已被特性膏药还原。
LAbilityPatchUsed = 特性已被特性膏药修改。
LAbilityUnexpected = 特性对于该种类/形态非法。
LAwakenedCap = 单个觉醒值不能大于 {0}。
LAwakenedShouldBeValue = 单个觉醒值应该大于 {0} ({1})。
LBallAbility = 不能以该球捕获隐藏特性。
LBallEggCherish = 一般的蛋不能为贵重球。
LBallEggMaster = 一般的蛋不能为大师球。
LBallEnc = 对于相遇方式球种合法。
LBallEncMismatch = 对于相遇方式为非法球种。
LBallHeavy = 体重轻, 低捕获率的宝可梦不能被沉重球捕获(7代)。
LBallNone = 没有满足条件的检查,假设为非法。
LBallSpecies = 不能以该球捕获宝可梦。
LBallSpeciesPass = 球对该种类合法。
LBallUnavailable = 在原来世代该球不可获得。
LContestSheenTooHigh_0 = 华丽大赛光泽度应 <= {0}。
LContestSheenTooLow_0 = 华丽大赛光泽度应 >= {0}。
LContestZero = 华丽大赛状态值应为0。
LContestZeroSheen = 华丽大赛光泽度应为0。
LDateOutsideConsoleWindow = 本地日期超出主机日期范围。
LDateOutsideDistributionWindow = 相遇日期在配信日期区间之外。
LDateTimeClockInvalid = 本地时间不符合有效时间戳格式。
LEffort2Remaining = 剩下2点努力值。
LEffortAbove252 = 单项努力值不能超过252。
LEffortAbove510 = 努力值总和不能超过510。
LEffortAllEqual = 所有努力值相等。
LEffortCap100 = 对于相遇等级为100的4代宝可梦,单项努力值不能大于100。
LEffortEgg = 蛋不能有努力值。
LEffortEXPIncreased = 所有努力值为0但当前等级高于相遇等级。
LEffortShouldBeZero = 无法获得努力值。
LEffortUntrainedCap = 有努力值但没有超过{0}的经验值。
LEggContest = 不能增加蛋的华丽大赛状态。
LEggEXP = 蛋不能获得经验值。
LEggFMetLevel_0 = 非法相遇等级, 应该是 {0}。
LEggHatchCycles = 蛋剩余孵化周期非法。
LEggLocation = 能在相遇地点孵化蛋。
LEggLocationInvalid = 不能在相遇地点孵化蛋。
LEggLocationNone = 非法蛋取得场所, 应该为空。
LEggLocationPalPark = 非法相遇地点, 应该是伙伴公园。
LEggLocationTrade = 能在相遇地点孵化交易的蛋。
LEggLocationTradeFail = 非法蛋取得场所, 不能在还是蛋时“交换”
LEggMetLocationFail = 不能在蛋取得场所获得蛋。
LEggNature = 不能改变蛋的能力性格(薄荷)。
LEggPokeathlon = 蛋不能有全能竞技赛体能值。
LEggPokerus = 蛋不能感染宝可病毒。
LEggPP = 蛋不能有PP数变动。
LEggPPUp = 不能对蛋使用PP提升剂。
LEggRelearnFlags = 蛋没有回忆招式。
LEggShinyLeaf = 蛋不能有闪光树叶/王冠。
LEggShinyPokeStar = 蛋无法成为宝可梦好莱坞之星。
LEggSpecies = 不能获得该种宝可梦的蛋。
LEggUnhatched = 合法孵化的蛋。
LEncCondition = 合法野外相遇方式。
LEncConditionBadRNGFrame = 相遇方式无法与可能的乱数帧匹配。
LEncConditionBadSpecies = 该宝可梦在来源版本中不存在。
LEncConditionBlack = 合法野外相遇方式 (黑色玻璃哨)。
LEncConditionBlackLead = 合法野外相遇方式 (黑色玻璃哨 & 压迫感/活力/干劲)。
LEncConditionDexNav = 合法野外相遇方式 (忍足系统)。
LEncConditionLead = 合法野外相遇方式 (压迫感/活力/干劲)。
LEncConditionWhite = 合法野外相遇方式 (白色玻璃哨)。
LEncConditionWhiteLead = 合法野外相遇方式 (白色玻璃哨 & 压迫感/活力/干劲)。
LEncGift = 无法在来源版本中匹配到相应的礼物蛋。
LEncGiftEggEvent = 无法在来源版本中匹配到相应的配信蛋。
LEncGiftIVMismatch = 个体值与神秘礼物数据不一致。
LEncGiftNicknamed = 配信宝可梦被改名。
LEncGiftNotFound = 不能与数据库中神秘礼物匹配。
LEncGiftPIDMismatch = 神秘礼物与 PID 不一致。
LEncGiftShinyMismatch = 神秘礼物与异色状态不一致。
LEncGiftVersionNotDistributed = 神秘礼物不能被该版本接收。
LEncInvalid = 不能在来源版本中找到对应相遇方式。
LEncMasteryInitial = 初始精通招式与期望的相遇状态不匹配。
LEncStaticMatch = 合法的礼物/定点相遇。
LEncStaticPIDShiny = 定点相遇异色条件不匹配。
LEncStaticRelearn = 定点相遇宝可梦,可回忆招式不匹配。
LEncTradeChangedNickname = 游戏内连接交换的昵称被修改。
LEncTradeChangedOT = 游戏内连接交换的初训家被修改。
LEncTradeIndexBad = 游戏内连接交换序号非法?
LEncTradeMatch = 合法的游戏内连接交换。
LEncTradeUnchanged = 游戏内连接交换的初训家和昵称未被修改。
LEncTypeMatch = 相遇类型与相遇方式一致。
LEncTypeMismatch = 相遇类型与相遇方式不一致。
LEncUnreleased = 未解禁配信。
LEncUnreleasedEMewJP = 非日版来自边境的小岛的梦幻,未发布的配信。
LEncUnreleasedHoOArceus = 来自初始之间的阿尔宙斯,未发布的配信。
LEncUnreleasedPtDarkrai = 非白金版来自新月岛的达克莱伊,未发布的配信。
LEncUnreleasedPtShaymin = 非白金版来自花之乐园的谢米,未发布的配信。
LEReaderAmerica = 美版E卡树果在日版存档中。
LEReaderInvalid = 非法E卡树果。
LEReaderJapan = 日版E卡树果在国际版存档中。
LEvoInvalid = 进化形态非法(或等级/交换进化型非法)。
LEvoTradeReq = 游戏内交换{0}应当进化为{1}。
LEvoTradeReqOutsider = 外来的{0}应当进化为{1}。
LEvoTradeRequired = 版本特定进化需要交换到另一版本。需要有最近持有人。
LFateful = 特殊游戏内宝可梦命中注定般地相遇。
LFatefulGiftMissing = 没有匹配的“命中注定相遇”的数据。该神秘礼物有被共享吗?
LFatefulInvalid = 命中注定般地相遇不应被勾选。
LFatefulMissing = 特殊游戏内宝可梦缺失命中注定般地相遇。
LFatefulMystery = 神秘礼物命中注定般地相遇。
LFatefulMysteryMissing = 神秘礼物缺失命中注定般地相遇。
LFavoriteMarkingUnavailable = 最喜欢的标志不可用。
LFormArgumentHigh = 形态参数对于当前 形态来说太高。
LFormArgumentInvalid = 形态参数无效。
LFormArgumentLow = 形态参数对于当前 形态来说太低。
LFormArgumentNotAllowed = 当前相遇方式不允许此 形态参数。
LFormArgumentValid = 形态参数有效。
LFormBattle = 该形态不可能存在对战外。
LFormEternal = 永恒之花相遇合法。
LFormEternalInvalid = 永恒之花相遇非法。
LFormInvalidExpect_0 = 形态非法,期望形态编号应为 {0}。
LFormInvalidGame = 这种形态不能在来源版本中获得。
LFormInvalidNature = 此形态无法拥有这种性格。
LFormInvalidRange = 形态数超过最大值。 应该 <= {0}, 实际是 {1}。
LFormItem = 持有物与形态一致。
LFormItemInvalid = 持有物与形态不一致。
LFormParty = 该形态不可能存在同行队伍外。
LFormPikachuCosplay = 只有换装皮卡丘能有该形态。
LFormPikachuCosplayInvalid = 换装皮卡丘不能有普通形态。
LFormPikachuEventInvalid = 配信皮卡丘不能有普通形态。
LFormValid = 合法形态。
LFormVivillon = 合法彩粉蝶花纹。
LFormVivillonEventPre = 退化形态拥有配信彩粉蝶花纹。
LFormVivillonInvalid = 非法彩粉蝶花纹。
LFormVivillonNonNative = 非本土彩粉蝶花纹。
LG1CatchRateChain = 捕获率不能与该宝可梦进化链内种族一致。
LG1CatchRateEvo = 捕获率与不计相遇方式的种族一致。应为进化前捕获率。
LG1CatchRateItem = 捕获率与合法二代持有物一致。
LG1CatchRateMatchPrevious = 捕获率与进化链中某种一致。
LG1CatchRateMatchTradeback = 捕获率与合法二代持有物一致。
LG1CatchRateNone = 捕获率不能与该宝可梦进化链内种族或2代持有物一致。
LG1CharNick = 来自1/2代的昵称使用了非法字符。
LG1CharOT = 来自1/2代的初训家名使用了非法字符。
LG1GBEncounter = 不能在VC中特殊相遇该种宝可梦。
LG1MoveExclusive = 初代专属招式。与无法追踪的遗传招式冲突。
LG1MoveLearnSameLevel = 不共存招式。 在四色中同一等级的升级招式。
LG1MoveTradeback = 无法追踪的遗传招式。与初代专属招式冲突。
LG1OTEvent = 不正确初代四色配信初训家名。
LG1OTGender = 第1/2世代的初训家不能为女性。
LG1Stadium = 不正确竞技场初训家。
LG1StadiumInternational = 合法国际版竞技场初训家。
LG1StadiumJapanese = 合法日版竞技场初训家。
LG1TradebackPreEvoMove = 无法追踪的进化前招式。与第一世代专属招式不兼容。
LG1Type1Fail = 第一属性错误, 与宝可梦本身的属性不符。
LG1Type2Fail = 第二属性错误, 与宝可梦本身的属性不符。
LG1TypeMatch1 = 第一属性合法, 与宝可梦本身的属性一致。
LG1TypeMatch2 = 第二属性合法, 与宝可梦本身的属性一致。
LG1TypeMatchPorygon = 多边兽的第一属性与第二属性均合法。
LG1TypePorygonFail = 多边兽的第一属性和第二属性均错误,不符合合法的属性组合。
LG1TypePorygonFail1 = 多边兽的第一属性错误。
LG1TypePorygonFail2 = 多边兽的第二属性错误。
LG2InvalidTilePark = 自然公园钓鱼遇敌。无法到达的水域。
LG2InvalidTileR14 = 关都14号道路钓鱼遇敌。无法到达的水域。
LG2InvalidTileSafari = 第二世代狩猎区钓鱼遇敌。无法到达的区域。
LG2InvalidTileTreeID = 匹配到水晶版头锤遇敌的一棵无法到达的树符合初训家ID。
LG2InvalidTileTreeNotFound = 无法在水晶版找到头锤遇敌的树符合初训家ID。
LG2OTGender = 除水晶版之外的虚拟主机游戏中初训家不能为女性。
LG2TreeID = 匹配到水晶版头锤遇敌的一棵树符合初训家ID。
LG3EReader = 非日版黑暗E卡宝可梦。未解禁相遇方式。
LG3OTGender = 来自圆形竞技场/XD的初训家不能为女性。
LG4InvalidTileR45Surf = 城都45号水路的水面相遇类型不可到达的水路。
LG5ID_N = N的初训家或表里ID不正确。
LG5IVAll30 = N的宝可梦所有个体值应为30。
LG5OTGenderN = N的宝可梦初训家性别必须为男性。
LG5PIDShinyGrotto = 在隐藏洞穴捕获的宝可梦不能为异色。
LG5PIDShinyN = N的宝可梦不能为异色。
LG5SparkleInvalid = 特殊游戏内宝可梦N的闪光标记不应勾选。
LG5SparkleRequired = 特殊游戏内宝可梦N的闪光标记缺失。
LGanbaruStatTooHigh = 一项或多项奋斗等级超过上限 (10 - IV个体值提升等级)。
LGenderInvalidNone = 无性别宝可梦不能有性别。
LGeoBadOrder = 地理位置回忆: 间隔/空白存在。
LGeoHardwareInvalid = 地理位置: 国家不在3DS区域内。
LGeoHardwareRange = 非法主机系统。
LGeoHardwareValid = 地理位置: 国家在3DS区域内。
LGeoMemoryMissing = 地理位置回忆: 回忆应该存在。
LGeoNoCountryHT = 地理位置回忆: 持有人名称存在但没有故居。
LGeoNoRegion = 地理位置回忆: 地区没有国家。
LHyperPerfectAll = 不能对完美个体的宝可梦极限特训。
LHyperPerfectOne = 不能对完美个体项极限特训。
LHyperPerfectUnavailable = 无法对任意一项个体值做极限特训。
LHyperTooLow_0 = 不能对未满{0}级的宝可梦极限特训。
LItemEgg = 蛋不能有持有物。
LItemUnreleased = 持有物未解禁。
LIVAllEqual_0 = 所有个体值都是 {0}。
LIVF_COUNT0_31 = 至少有 {0} 项个体值 = 31。
LIVNotCorrect = 个体值与相遇要求不匹配
LLevelEXPThreshold = 当前经验与等级匹配。
LLevelEXPTooHigh = 当前经验值超过此宝可梦100级的经验值上限。
LLevelMetBelow = 当前等级低于相遇等级。
LLevelMetGift = 相遇等级与神秘礼物等级不一致。
LLevelMetGiftFail = 相遇等级低于神秘礼物等级。
LLevelMetSane = 当前等级不低于相遇等级。
LMarkValueOutOfRange_0 = 索引{0}的标记不在允许的范围内。
LMarkValueShouldBeZero = 无法设置标记。
LMarkValueUnusedBitsPresent = 标记值超过可访问的范围。
LMemoryArgBadCatch = {0} 回忆: {0} 没有捕获它。
LMemoryArgBadHatch = {0} 回忆: {0} 没有孵化它。
LMemoryArgBadHT = 回忆: 蛋不能作为持有人的回忆。
LMemoryArgBadID = {0} 回忆: 不能在 {0} 版中获得回忆。
LMemoryArgBadItem = {0} 回忆: 该宝可梦不能持有此物品。
LMemoryArgBadLocation = {0} 回忆: 不能在 {0} 版中获得地点。
LMemoryArgBadMove = {0} 回忆: 当前种类不能习得该招式。
LMemoryArgBadOTEgg = {0} 回忆: 连接交换不能为第一回忆。
LMemoryArgBadSpecies = {0} 回忆: 不能在游戏中捕获。
LMemoryArgSpecies = {0} 回忆: 当前种类能在游戏中捕获。
LMemoryCleared = 回忆: 未完全清理。
LMemoryF_0_Valid = {0} 回忆有效。
LMemoryFeelInvalid = {0} 回忆: 非法感受。
LMemoryHTFlagInvalid = 未交换: 当前持有者不能为持有人。
LMemoryHTGender = 持有人性别非法: {0}
LMemoryHTLanguage = 持有人语言丢失。
LMemoryIndexArgHT = 应该有持有人回忆文本值(某处)。
LMemoryIndexFeel = {0} 回忆: 感受应为序号 {1}。
LMemoryIndexFeelHT09 = 应该有持有人回忆感受值 0-9。
LMemoryIndexID = {0} 回忆: 应为序号 {1}。
LMemoryIndexIntensity = {0} 回忆: 回忆强度应为序号 {1}。
LMemoryIndexIntensityHT1 = 应该有持有人回忆强度值(1st)。
LMemoryIndexIntensityMin = {0} 回忆: 回忆强度应不小于 {1}。
LMemoryIndexLinkHT = 应该有连接交换持有人的回忆。
LMemoryIndexVar = {0} 回忆: 文本值应为序号 {1}。
LMemoryMissingHT = 回忆: 缺失持有人回忆。
LMemoryMissingOT = 回忆: 缺失初训家回忆。
LMemorySocialTooHigh_0 = 社交度应 <= {0}
LMemorySocialZero = 社交度应为0。
LMemoryStatAffectionHT0 = 未交换: 持有人的友好度应为0。
LMemoryStatAffectionOT0 = 初训家友好度应为0。
LMemoryStatEnjoyment = 享受度应该为{0}。
LMemoryStatFriendshipHT0 = 未交换: 持有人的亲密度应为0。
LMemoryStatFriendshipOTBaseEvent = 配信的初训家亲密度与初始亲密度不一致。
LMemoryStatFullness = 饱腹度应该为{0}。
LMetDetailTimeOfDay = 相遇时间不在预期范围内。
LMoveEggFIncompatible0_1 = {0}的遗传招式。与遗传的招式{1}不共存。
LMoveEggIncompatible = 遗传招式。与配信蛋招式冲突。
LMoveEggIncompatibleEvent = 配信蛋招式。与遗传招式冲突。
LMoveEggInherited = 遗传了蛋招式。
LMoveEggInheritedTutor = 遗传了教学招式。
LMoveEggInvalid = 不应有的遗传招式
LMoveEggInvalidEvent = 遗传了遗传招式。配信的蛋不应有。
LMoveEggInvalidEventLevelUp = 遗传了升级招式。配信的蛋不应有。
LMoveEggInvalidEventLevelUpGift = 遗传升级招式。礼物蛋不应有。
LMoveEggInvalidEventTMHM = 遗传了TM/HM招式。配信的蛋不应有。
LMoveEggInvalidEventTutor = 遗传了教学招式。配信的蛋不应有。
LMoveEggLevelUp = 遗传了升级招式。
LMoveEggMissing = 缺失配信蛋招式。
LMoveEggMoveGift = 遗传招式。礼物蛋不应有。
LMoveEggTMHM = 遗传了TM/HM招式。
LMoveEventEggLevelUp = 遗传升级招式。与配信蛋招式冲突。
LMoveEvoFCombination_0 = 招式组合与{0}进化型不兼容。
LMoveEvoFHigher = 不共存进化招式。招式 {1} 比其他招式 {0} 习得等级高。
LMoveEvoFLower = 不共存进化招式。招式 {0} 比其他招式 {1} 习得等级低。
LMoveFDefault_0 = 在第{0}世代的默认招式。
LMoveFExpect_0 = 应该是该招式: {0}
LMoveFExpectSingle_0 = 预期: {0}
LMoveFLevelUp_0 = 在第{0}世代通过升级习得。
LMoveFTMHM_0 = 在第{0}世代通过TM/HM习得。
LMoveFTutor_0 = 在第{0}世代通过招式教学习得。
LMoveKeldeoMismatch = 凯路迪欧的招式与形态不匹配。
LMoveNincada = 只能拥有一个铁面忍者的招式。
LMoveNincadaEvo = 通过土居忍士进化为铁面忍者习得。
LMoveNincadaEvoF_0 = 通过土居忍士在第{0}世代进化为铁面忍者习得。
LMovePPExpectHealed_0 = 招式 {0} 的PP恢复量未达预期值
LMovePPTooHigh_0 = 招式 {0} PP高于允许值。
LMovePPUpsTooHigh_0 = 招式 {0} PP上升高于允许值。
LMoveRelearnDexNav = 非正确忍足系统相遇的招式。
LMoveRelearnEgg = 基本遗传招式。
LMoveRelearnEggMissing = 缺失基本遗传招式。
LMoveRelearnFExpect_0 = 应为以下可回忆招式: {0} ({1})
LMoveRelearnFMiss_0 = 缺失可回忆招式: {0}
LMoveRelearnInvalid = 非正确回忆招式。
LMoveRelearnNone = 应该没有回忆招式。
LMoveRelearnUnderground = 非地下大洞窟蛋招式。
LMoveShopAlphaMoveShouldBeMastered = 头目招式应标记为精通。
LMoveShopAlphaMoveShouldBeOther = 头目相遇方式与此头目招式不匹配。
LMoveShopAlphaMoveShouldBeZero = 只有头目才可能拥有头目招式池。
LMoveShopMasterInvalid_0 = 无法手动精通 {0} 不允许精通。
LMoveShopMasterNotLearned_0 = 无法手动精通 {0} 无法习得升级招式。
LMoveShopPurchaseInvalid_0 = 无法从商店习得 {0} 招式。
LMoveSourceDefault = 默认招式。
LMoveSourceDuplicate = 重复招式。
LMoveSourceEgg = 遗传招式。
LMoveSourceEggEvent = 配信蛋招式。
LMoveSourceEmpty = 空招式。
LMoveSourceInvalid = 招式非法。
LMoveSourceInvalidSketch = 招式非法 (写生)。
LMoveSourceLevelUp = 通过升级习得。
LMoveSourceRelearn = 可回忆招式。
LMoveSourceShared = 共享的不可回忆招式。
LMoveSourceSharedF = 共享的{0}代不可回忆招式。
LMoveSourceSpecial = 特殊不可回忆招式。
LMoveSourceTMHM = 通过TM/HM习得。
LMoveSourceTR = 意外的招式学习机标志: {0}
LMoveSourceTutor = 通过招式教学习得。
LNickFlagEggNo = 蛋不能被改名。
LNickFlagEggYes = 蛋必须有昵称。
LNickInvalidChar = 无法给宝可梦取中文昵称。
LNickLengthLong = 昵称太长。
LNickLengthShort = 昵称为空。
LNickMatchLanguage = 昵称与种类名一致。
LNickMatchLanguageEgg = 蛋名称与语言一致。
LNickMatchLanguageEggFail = 蛋名称与语言不一致。
LNickMatchLanguageFail = 昵称与种类名不一致。
LNickMatchLanguageFlag = 昵称被标记, 与种类名一致。
LNickMatchNoOthers = 昵称不与另一种类名一致。
LNickMatchNoOthersFail = 昵称与另一宝可梦种类名一致 (+语言)。
LOT_IDEqual = 表里ID相等。
LOT_IDInvalid = 表里ID组合不可能在游戏中获得。
LOT_IDs0 = 表ID与里ID为 0。
LOT_SID0 = 里ID为0。
LOT_SID0Invalid = 里ID应为 0。
LOT_TID0 = 表ID为0。
LOTLanguage = 语言ID应该 {0}, 而不是 {1}。
LOTLong = 初训家名称太长。
LOTShort = 初训家名太短
LOTSuspicious = 可疑的初训家信息。
LPIDEncryptWurmple = 刺尾虫进化形态与加密常数不一致。
LPIDEncryptZero = 未设置加密常数。
LPIDEqualsEC = 加密常数与PID一致。
LPIDGenderMatch = 性别与PID匹配。
LPIDGenderMismatch = 性别与PID不匹配。
LPIDNatureMatch = 性格与PID匹配。
LPIDNatureMismatch = 性格与PID不匹配。
LPIDTypeMismatch = 相遇类型与 PID 不一致。
LPIDZero = 未设置PID。
LPokerusDaysTooHigh_0 = 宝可病毒剩余时间过长; 应 <= {0}。
LPokerusStrainUnobtainable_0 = 宝可病毒种类 {0} 不可获得
LRibbonAllValid = 所有奖章合法。
LRibbonEgg = 蛋不能接受奖章。
LRibbonFInvalid_0 = 非法奖章:
LRibbonFMissing_0 = 缺失奖章:
LRibbonMarkingAffixedF_0 = 无效的奖章/证章: {0}
LRibbonMarkingFInvalid_0 = 无效标记: {0}
LStatAlphaInvalid = 头目标记不匹配。
LStatBattleVersionInvalid = 对战版本不在期望范围内。
LStatDynamaxInvalid = 极巨等级不在预期范围内。
LStatGigantamaxInvalid = 超极巨标志不匹配。
LStatGigantamaxValid = 超极巨标志已被极巨汤修改。
LStatIncorrectCP = 计算的CP值与存储值不匹配。
LStatIncorrectHeight = 计算的身高数据与存储值不匹配
LStatIncorrectHeightCopy = 复制身高数据与原始身高值不匹配。
LStatIncorrectHeightValue = 身高数据与期望身高值不匹配。
LStatIncorrectWeight = 计算的体重数据与存储值不匹配
LStatIncorrectWeightValue = 体重数据与期望体重值不匹配。
LStatInvalidHeightWeight = 身高或体重值在统计学意义上不可获得。
LStatNatureInvalid = 性格不在期望范围内。
LStatNobleInvalid = 王标记非法。
LStoredSourceEgg = 蛋必须放在盒子里或野餐篮里。
LStoredSourceInvalid_0 = 无效的存储源: {0}
LSuperComplete = 超级训练完成标记不匹配。
LSuperDistro = 配信超级训练任务未发布。
LSuperEgg = 不能对蛋进行超级训练。
LSuperNoComplete = 当前来源版本不能有超级训练完成的标记。
LSuperNoUnlocked = 当前来源版本不能有超级训练解锁的标记。
LSuperUnavailable = 所达游戏版本不能进行超级训练。
LSuperUnused = 未使用的超级训练旗标被标记。
LTeraTypeIncorrect = 太晶属性与期望值不匹配。
LTeraTypeMismatch = 太晶属性与宝可梦默认属性不匹配。
LTradeNotAvailable = 该相遇方式无法被交换到当前持有训练家手上。
LTrainerIDNoSeed = 训练家ID无法通过任何随机数种子生成。
LTransferBad = 不能在VC中获得该种宝可梦。
LTransferCurrentHandlerInvalid = 非法当前持有训练家信息,存档中训练家信息是另一个值。
LTransferEgg = 不能跨世代传送蛋。
LTransferEggLocationTransporter = 非法相遇地点, 应该是宝可梦传送。
LTransferEggMetLevel = 对于传送,相遇等级非法。
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = 游戏中被标记为非法(使用了游戏bug)。
LTransferHTFlagRequired = 当前持有人不能与该宝可梦的初训家为同一人(包括同世代不同游戏)。
LTransferHTMismatchGender = 处理训练家的性别与期望的训练家性别不符。
LTransferHTMismatchLanguage = 持有训练家与期望训练家语言不匹配。
LTransferHTMismatchName = 持有训练家与期望训练家名字不匹配。
LTransferMet = 非法相遇地点,应该为传送或王冠。
LTransferMetLocation = 传送相遇地点非法。
LTransferMove = 不兼容的宝可梦传送招式。
LTransferMoveG4HM = 清除浓雾与潮旋。两者在传到5代以前必须被移除。
LTransferMoveHM = 第{0}世代秘传学习器HM招式。应在传至第{1}世代前被移除。
LTransferNature = 对于传送非法的性格
LTransferNotPossible = 无法从原始格式转换为当前格式。
LTransferObedienceLevel = 听话等级非法,未交换时应为相遇等级,交换后应大于等于相遇等级。
LTransferOriginFInvalid0_1 = {0}来源的宝可梦不能存在于({1})的游戏记录。
LTransferPIDECBitFlip = PID应与加密常数相等[第一位反转]!
LTransferPIDECEquals = PID应与加密常数相等!
LTransferPIDECXor = 加密常数与异色xor的PID匹配。
LTransferTrackerMissing = Pokémon HOME传输追踪信息丢失。
LTransferTrackerShouldBeZero = Pokémon HOME传输追踪信息应为0。
LTrashBytesExpected = 预期的垃圾字节。
LTrashBytesExpected_0 = 预期的垃圾字节:{0}
LTrashBytesMismatchInitial = 期望的初始垃圾字节应与相遇匹配。
LTrashBytesMissingTerminator = 缺少最终结束符。
LTrashBytesShouldBeEmpty = 垃圾字节应被清除。
LTrashBytesUnexpected = 非预期的垃圾字节。

View File

@ -1,423 +0,0 @@
L_AError = 內部錯誤。
L_ALegal = 合法。
L_AnalysisUnavailable = 無法解析此寶可夢。
L_AValid = 有效。
L_F0_1 = {0}: {1}
L_F0_M_1_2 = {0}招式 {1} : {2}
L_F0_RM_1_2 = {0}可回憶招式 {1}: {2}
L_FEncounterType_0 = 遇見方式: {0}
L_FOriginSeed_0 = 原始 Seed: {0}
L_FPIDType_0 = PID類型: {0}
L_SFishy = 可疑
L_SInvalid = 不合法
L_SNotImplemented = 功能尚未實現
L_SValid = 合法
L_XEnigmaBerry_0 = {0}果
L_XHT = 持有人
L_XKorean = 韓版
L_XKoreanNon = 非韓版
L_XLocation = Location
L_XMatches0_1 = 匹配: {0} {1}
L_XNickname = Nickname
L_XOT = 初訓家
L_XRareFormEvo_0_1 = 將進化為「{0}」形態(該寶可夢種類之「{1}」形態更爲稀有)
L_XWurmpleEvo_0 = 刺尾蟲進化形態: {0}
LAbilityCapsuleUsed = 特性經已透過特性膠囊改變。
LAbilityFlag = 特性與特性序號匹配。
LAbilityHiddenFail = 隱藏特性與遇見方式不匹配。
LAbilityHiddenUnavailable = 隱藏特性不可獲得。
LAbilityMismatch = 特性與遇見方式不匹配。
LAbilityMismatch3 = 特性與第三世代種類特性不匹配。
LAbilityMismatchFlag = 特性與特性值不匹配。
LAbilityMismatchGift = 特性與神秘禮物記載數據不匹配。
LAbilityMismatchGrotto = 隱藏洞穴捕獲之寶可夢必定為隱藏特性。
LAbilityMismatchHordeSafari = 非群戰/朋友原野區獲得隱藏特性。
LAbilityMismatchPID = 特性與 PID 記載數據不匹配。
LAbilityMismatchSOS = 非幫手寶可夢擁有隱藏特性。
LAbilityPatchRevertUsed = 特性經已透過特性膏藥還原。
LAbilityPatchUsed = 特性經已透過特性膏藥改變。
LAbilityUnexpected = 特性對於該種類/形態不合法。
LAwakenedCap = 單個覺醒值不能大於 {0}。
LAwakenedShouldBeValue = 單個覺醒值應該大於 {0} ({1})。
LBallAbility = 不能使用該球種捕獲此種隱藏特性寶可夢。
LBallEggCherish = 普通蛋之球種不能為貴重球。
LBallEggMaster = 普通蛋之球種不能為大師球。
LBallEnc = 可使用此球種獲得該遇見方式寶可夢。
LBallEncMismatch = 不可使用此球種獲得該遇見方式寶可夢。
LBallHeavy = 體重輕且低捕獲率之寶可夢無法被沉重球所捕獲(第七世代)。
LBallNone = 未檢查到滿足條件之資訊,因而假設為不合法。
LBallSpecies = 無法使用此球種捕獲該寶可夢。
LBallSpeciesPass = 可使用此球種捕獲該種類寶可夢。
LBallUnavailable = 於此寶可夢出身游戲世代中,該球種不可獲得。
LContestSheenTooHigh_0 = 華麗大賽光澤度應小於或等於「 {0} 」。
LContestSheenTooLow_0 = 華麗大賽光澤度應大於或等於「 {0} 」。
LContestZero = 華麗大賽狀態值應置「0」。
LContestZeroSheen = 華麗大賽光澤度應置「0」。
LDateOutsideConsoleWindow = Local Date is outside of console's local time window.
LDateOutsideDistributionWindow = 遇見日期於神秘禮物配信期間之外。
LDateTimeClockInvalid = Local Time is not a valid timestamp.
LEffort2Remaining = 仍餘下2點努力值尚未分配。
LEffortAbove252 = 單項努力值不能超過「252」。
LEffortAbove510 = 努力值總和不能超過「510」。
LEffortAllEqual = 所有努力值相等。
LEffortCap100 = 對於遇見等級為100之四代寶可夢,單項努力值不能大於「100」。
LEffortEgg = 蛋不能擁有努力值。
LEffortEXPIncreased = 所有努力值為0但當前等級高於遇見等級。
LEffortShouldBeZero = 無法獲得努力值。
LEffortUntrainedCap = 寶可夢擁有努力值,但尚未獲得超過{0}之經驗值。
LEggContest = 不能調整蛋之華麗大賽狀態。
LEggEXP = 蛋不能獲得經驗值。
LEggFMetLevel_0 = 不合法之遇見等級, 應於「 {0} 」級時遇見該寶可夢。
LEggHatchCycles = 蛋剩餘孵化週期不合法。
LEggLocation = 可於遇見地點孵化蛋。
LEggLocationInvalid = 不能於遇見地點孵化蛋。
LEggLocationNone = 不合法之蛋取得場所, 應該為「空」。
LEggLocationPalPark = 不合法之遇見地點, 應於「夥伴公園」遇見該寶可夢。
LEggLocationTrade = 可於遇見地點孵化「連線交換」所得蛋。
LEggLocationTradeFail = 不合法之蛋取得場所, 無法於寶可夢仍是蛋時「連線交換」。
LEggMetLocationFail = 無法於設定之蛋取得場所獲得該蛋。
LEggNature = 無法使用「薄荷」修正蛋之性格。
LEggPokeathlon = 蛋不能有全能競技賽體能值。
LEggPokerus = 蛋不能感染寶可病毒。
LEggPP = 蛋不能修改 PP 值。
LEggPPUp = 不能對蛋使用 PP 提升劑。
LEggRelearnFlags = 預期不會重新學習技能標記。
LEggShinyLeaf = 蛋不能携帶閃耀的葉片/王冠。
LEggShinyPokeStar = 蛋無法成為寶可夢好萊塢之星。
LEggSpecies = 不能獲得該種寶可夢之蛋。
LEggUnhatched = 合法孵化之蛋。
LEncCondition = 合法野外遇見方式。
LEncConditionBadRNGFrame = 遇見方式可能無法與可行之亂數幀相匹配。
LEncConditionBadSpecies = 該寶可夢於出身游戲中不存在。
LEncConditionBlack = 合法野外遇見方式 (黑色玻璃哨)。
LEncConditionBlackLead = 合法野外遇見方式 (黑色玻璃哨 & 壓迫感/活力/幹勁)。
LEncConditionDexNav = 合法野外遇見方式 (忍足系統)。
LEncConditionLead = 合法野外遇見方式 (壓迫感/活力/幹勁)。
LEncConditionWhite = 合法野外遇見方式 (白色玻璃哨)。
LEncConditionWhiteLead = 合法野外遇見方式 (白色玻璃哨 & 壓迫感/活力/幹勁)。
LEncGift = 無法於出身游戲中匹配到相應之神秘禮物蛋。
LEncGiftEggEvent = 無法於出身游戲中匹配到相應之神秘禮物蛋。
LEncGiftIVMismatch = 個體值與神秘禮物記載資料不匹配。
LEncGiftNicknamed = 神秘禮物配信寶可夢經已修改過昵稱。
LEncGiftNotFound = 不能與資料庫中神秘禮物資料匹配。
LEncGiftPIDMismatch = 神秘禮物記載數據與 PID 不匹配。
LEncGiftShinyMismatch = 神秘禮物記載數據與異色狀態不匹配。
LEncGiftVersionNotDistributed = 不能於此游戲版本中接收該神秘禮物。
LEncInvalid = 不能於出身游戲中匹配到對應遇見方式。
LEncMasteryInitial = 初始精通技能標識無法與期望狀態匹配。
LEncStaticMatch = 合法之神秘禮物/定點遇見。
LEncStaticPIDShiny = 定點遇見類型寶可夢之異色條件不匹配。
LEncStaticRelearn = 定點遇見寶可夢之可回憶招式不匹配。
LEncTradeChangedNickname = 遊戲內連線交換之昵稱經已修改。
LEncTradeChangedOT = 遊戲內連線交換之初訓家經已修改。
LEncTradeIndexBad = 遊戲內連線交換序號不合法?
LEncTradeMatch = 合法之遊戲內連線交換。
LEncTradeUnchanged = 遊戲內連線交換之初訓家和昵稱未被修改。
LEncTypeMatch = 遇見類型與資料記載之遇見方式匹配。
LEncTypeMismatch = 遇見類型與資料記載之遇見方式不匹配。
LEncUnreleased = 未解禁之神秘禮物。
LEncUnreleasedEMewJP = 非日版游戲來自邊境小島之夢幻,未發佈之配信。
LEncUnreleasedHoOArceus = 來自初始之間的阿爾宙斯,未發佈之配信。
LEncUnreleasedPtDarkrai = 非白金版游戲來自新月島之達克萊伊,未發佈之配信。
LEncUnreleasedPtShaymin = 非白金版游戲來自花之樂園的謝米,未發佈之配信。
LEReaderAmerica = 美版E-Reader樹果載入到了日版儲存資料中。
LEReaderInvalid = 不合法E-Reader樹果。
LEReaderJapan = 日版E-Reader樹果載入到了國際版儲存資料中。
LEvoInvalid = 應暫無法進化為此寶可夢(可能由於等級,通訊進化或其餘條件未滿足)。
LEvoTradeReq = 遊戲內連線交換「{0}」應通訊進化進化為「{1}」。
LEvoTradeReqOutsider = 外來之「{0}」應當進化為「{1}」。
LEvoTradeRequired = 該特定進化為版本獨占,須交換至另一版本中進化,因而須有現時持有人資訊。
LFateful = 遊戲內特殊寶可夢應有「命中注定般地遇見」之標識。
LFatefulGiftMissing = 缺乏匹配之「命中注定般地遇見」資料。此神秘禮物有被共用分享至資料庫嗎?
LFatefulInvalid = 「命中注定般地遇見」不應被勾選。
LFatefulMissing = 遊戲內特殊寶可夢缺失「命中注定般地遇見」之標識。
LFatefulMystery = 神秘禮物寶可夢應有「命中注定般地遇見」之標識。
LFatefulMysteryMissing = 神秘禮物缺失「命中注定般地遇見」之標識。
LFavoriteMarkingUnavailable = 最喜歡之標記不可用。
LFormArgumentHigh = 形態參數對於當前形態而言數值過高。
LFormArgumentInvalid = 形態參數無效。
LFormArgumentLow = 形態參數對於當前形態而言數值過低。
LFormArgumentNotAllowed = 當前遇見方式不應為此形態參數。
LFormArgumentValid = 形態參數有效。
LFormBattle = 該形態無法存在對戰外。
LFormEternal = 永恆之花遇見合法。
LFormEternalInvalid = 永恆之花遇見不合法。
LFormInvalidExpect_0 = 此形態不合法,預期之形態編號應為「 {0} 」。
LFormInvalidGame = 此形態不能於出身游戲中獲得。
LFormInvalidNature = 此形態無法擁有該種性格。
LFormInvalidRange = 形態數超過最大值。 應該 <=「 {0} 」, 實際是「 {1} 」。
LFormItem = 持有物與形態匹配。
LFormItemInvalid = 持有物與現時形態不匹配(可能此形態僅於持有某種持有物時生效)。
LFormParty = 該形態不可於同行隊伍外存在。
LFormPikachuCosplay = 僅換裝皮卡丘可擁有該形態。
LFormPikachuCosplayInvalid = 換裝皮卡丘不能有普通形態。
LFormPikachuEventInvalid = 神秘禮物配信皮卡丘不能有普通形態。
LFormValid = 合法形態。
LFormVivillon = 合法碧粉蝶花紋。
LFormVivillonEventPre = 退化形態擁有神秘禮物配信碧粉蝶花紋。
LFormVivillonInvalid = 不合法碧粉蝶花紋。
LFormVivillonNonNative = 此碧粉蝶花紋無法於本土生成。
LG1CatchRateChain = 捕獲率不能與該寶可夢進化鏈內種族資料匹配。
LG1CatchRateEvo = 捕獲率與不論遇見方式之種族匹配。應為進化前之捕獲率。
LG1CatchRateItem = 捕獲率與合法二代持有物匹配。
LG1CatchRateMatchPrevious = 捕獲率與進化鏈中某種類匹配。
LG1CatchRateMatchTradeback = 捕獲率與合法第二世代持有物匹配。
LG1CatchRateNone = 捕獲率不能與該寶可夢進化鏈內種族,或第二世代持有物匹配。
LG1CharNick = 來自第一、二世代之昵稱使用了非法字元。
LG1CharOT = 來自第一、二世代之初訓家名字使用了非法字元。
LG1GBEncounter = 不能於VC中特殊遇見該種寶可夢。
LG1MoveExclusive = 初代專屬招式,與無法追蹤之遺傳招式衝突。
LG1MoveLearnSameLevel = 不可共存招式, 為初代中同一等級升級時所選擇招式。
LG1MoveTradeback = 無法追蹤之遺傳招式。與初代專屬招式衝突。
LG1OTEvent = 不正確之初代配信初訓家名。
LG1OTGender = 第一、二世代之初訓家不能為女性。
LG1Stadium = 不正確圓形競技場初訓家。
LG1StadiumInternational = 合法國際版圓形競技場初訓家。
LG1StadiumJapanese = 合法日版圓形競技場初訓家。
LG1TradebackPreEvoMove = 無法追蹤之進化前招式。與第一世代專屬招式不相容。
LG1Type1Fail = 不合法類型A與種類不匹配。
LG1Type2Fail = 不合法類型B與種類不匹配。
LG1TypeMatch1 = 合法類型A與種族匹配。
LG1TypeMatch2 = 合法類型B與種族匹配。
LG1TypeMatchPorygon = 多邊獸有合法之類型A與B值。
LG1TypePorygonFail = 多邊獸有不合法之類型A或B值其組合情況不合法。
LG1TypePorygonFail1 = 多邊獸有不合法之類型A值。
LG1TypePorygonFail2 = 多邊獸有不合法之類型B值。
LG2InvalidTilePark = 為自然公園釣魚遇敵。但該水域無法到達。
LG2InvalidTileR14 = 關都14號道路釣魚遇敵。但該水域無法到達。
LG2InvalidTileSafari = 第二世代狩獵區釣魚遇敵。但該區域無法到達。
LG2InvalidTileTreeID = 匹配到水晶版頭錘遇敵。但該樹與初訓家ID不符合。
LG2InvalidTileTreeNotFound = 無法於水晶版找到符合初訓家ID的頭錘遇敵之樹。
LG2OTGender = 除水晶版之外的虛擬主機遊戲中初訓家不能為女性。
LG2TreeID = 匹配到水晶版頭錘遇敵之一棵樹符合初訓家ID。
LG3EReader = 非日版黑暗E-reader寶可夢。未解禁之遇見方式。
LG3OTGender = 來自圓形競技場/暗黑旋風XD之初訓家不能為女性。
LG4InvalidTileR45Surf = 城都45號道路之水面遇見類型但該水道不可到達。
LG5ID_N = N之初訓家名稱/十六位元表ID(TID16)/十六位元隱ID(SID16)不正確。
LG5IVAll30 = N的寶可夢所有個體值應為30。
LG5OTGenderN = N的寶可夢初訓家性別必須為男性。
LG5PIDShinyGrotto = 於隱藏洞穴捕獲之寶可夢不能為異色。
LG5PIDShinyN = N的寶可夢不能為異色。
LG5SparkleInvalid = 特殊遊戲內寶可夢N的異色標記不應勾選。
LG5SparkleRequired = 特殊遊戲內寶可夢N的異色標記缺失。
LGanbaruStatTooHigh = 一項或多項奮鬥等級超過上限 (10 減 IV 個體值提升奮鬥等級)。
LGenderInvalidNone = 無性別寶可夢不能有性別。
LGeoBadOrder = 地理位置回憶: 間隔/空白存在。
LGeoHardwareInvalid = 地理位置: 國家/地區不在3DS區域內。
LGeoHardwareRange = 不合法主機系統。
LGeoHardwareValid = 地理位置: 國家/地區在3DS區域內。
LGeoMemoryMissing = 地理位置回憶: 回憶應該存在。
LGeoNoCountryHT = 地理位置回憶: 持有人名稱存在但沒有故居。
LGeoNoRegion = 地理位置回憶: 地區沒有國家。
LHyperPerfectAll = 不能對完美個體之寶可夢極限特訓。
LHyperPerfectOne = 不能對完美個體項極限特訓。
LHyperPerfectUnavailable = 無法對任意一項個體值進行極限特訓。
LHyperTooLow_0 = 不能對未滿{0}級之寶可夢極限特訓。
LItemEgg = 蛋不能擁有持有物。
LItemUnreleased = 持有物未解禁。
LIVAllEqual_0 = 所有個體值均為「 {0} 」。
LIVF_COUNT0_31 = 至少有 {0} 項個體值 = 31。
LIVNotCorrect = 個體值與遇見要求不匹配。
LLevelEXPThreshold = 當前經驗值與等級匹配。
LLevelEXPTooHigh = 當前經驗值超過此寶可夢100級時之經驗值上限。
LLevelMetBelow = 當前等級低於遇見等級。
LLevelMetGift = 遇見等級與神秘禮物資料記載等級不匹配。
LLevelMetGiftFail = 遇見等級低於神秘禮物資料記載等級。
LLevelMetSane = 當前等級不低於遇見等級。
LMarkValueOutOfRange_0 = 索引 {0} 上之標記未於允許值内。
LMarkValueShouldBeZero = 不可設置標記。
LMarkValueUnusedBitsPresent = 標記使用之位元超過允許上限。
LMemoryArgBadCatch = {0} 回憶: {0} 沒有捕獲它。
LMemoryArgBadHatch = {0} 回憶: {0} 沒有孵化它。
LMemoryArgBadHT = 回憶: 蛋不能擁有現時持有人之回憶。
LMemoryArgBadID = {0} 回憶: 不能於 {0} 版中獲得回憶。
LMemoryArgBadItem = {0} 回憶: 該寶可夢不能持有此物品。
LMemoryArgBadLocation = {0} 回憶: 不能於 {0} 版中獲得該地點。
LMemoryArgBadMove = {0} 回憶: 當前種類寶可夢無法習得該招式。
LMemoryArgBadOTEgg = {0} 回憶: 連線交換不能為第一回憶。
LMemoryArgBadSpecies = {0} 回憶: 不能於遊戲中捕獲。
LMemoryArgSpecies = {0} 回憶: 當前種類能於遊戲中捕獲。
LMemoryCleared = 回憶: 未完全清理。
LMemoryF_0_Valid = {0} 回憶有效。
LMemoryFeelInvalid = {0} 回憶: 不合法感受。
LMemoryHTFlagInvalid = 未交換: 當前持有者不能為持有人。
LMemoryHTGender = 持有人性別不合法: {0}。
LMemoryHTLanguage = 持有人語言丟失。
LMemoryIndexArgHT = 應該有持有人回憶文本值(某處)。
LMemoryIndexFeel = {0} 回憶: 感受應為序號 {1}。
LMemoryIndexFeelHT09 = 應該有持有人回憶感受值 0-9。
LMemoryIndexID = {0} 回憶: 應為序號 {1}。
LMemoryIndexIntensity = {0} 回憶: 回憶強度應為序號 {1}。
LMemoryIndexIntensityHT1 = 應該有持有人回憶強度值(1st)。
LMemoryIndexIntensityMin = {0} 回憶: 回憶強度應不小於 {1}。
LMemoryIndexLinkHT = 應該有連線交換持有人之回憶。
LMemoryIndexVar = {0} 回憶: 文本值應為序號「 {1} 」。
LMemoryMissingHT = 回憶: 缺失現時持有人之回憶。
LMemoryMissingOT = 回憶: 缺失初訓家之回憶。
LMemorySocialTooHigh_0 = 社交度應 <= {0}。
LMemorySocialZero = 社交度應置「0」。
LMemoryStatAffectionHT0 = 未連線交換: 現時持有人之友好度應置0。
LMemoryStatAffectionOT0 = 初訓家友好度應置「0」。
LMemoryStatEnjoyment = 享受度應該為{0}。
LMemoryStatFriendshipHT0 = 未進行連線交換: 現時持有人之友好度應為置0。
LMemoryStatFriendshipOTBaseEvent = 神秘禮物配信之初訓家友好度與初始友好度不匹配。
LMemoryStatFullness = 飽腹度應該為{0}。
LMetDetailTimeOfDay = 寶可夢之遇見時段不在預期範圍内。
LMoveEggFIncompatible0_1 = {0}之遺傳招式。與遺傳之招式{1}不共存。
LMoveEggIncompatible = 遺傳招式。與神秘禮物配信蛋招式衝突。
LMoveEggIncompatibleEvent = 神秘禮物配信蛋招式。與遺傳招式衝突。
LMoveEggInherited = 遺傳了蛋招式。
LMoveEggInheritedTutor = 遺傳了教學招式。
LMoveEggInvalid = 不應習得之遺傳招式。
LMoveEggInvalidEvent = 神秘禮物蛋不應有遺傳招式。
LMoveEggInvalidEventLevelUp = 神秘禮物蛋不應遺傳升級招式。
LMoveEggInvalidEventLevelUpGift = 神秘禮物蛋不應遺傳升級招式。
LMoveEggInvalidEventTMHM = 神秘禮物蛋不應遺傳「招式學習器/秘傳學習器」招式。
LMoveEggInvalidEventTutor = 神秘禮物蛋不應遺傳教學招式。
LMoveEggLevelUp = 遺傳了升級招式。
LMoveEggMissing = 缺失神秘禮物配信蛋招式。
LMoveEggMoveGift = 神秘禮物蛋不應有遺傳招式。
LMoveEggTMHM = 遺傳了「招式學習器/秘傳學習器」招式。
LMoveEventEggLevelUp = 遺傳升級招式。與神秘禮物蛋招式衝突。
LMoveEvoFCombination_0 = 招式組合與{0}進化型不相容。
LMoveEvoFHigher = 不共存之進化招式。招式 {1} 比其他招式 {0} 習得等級高。
LMoveEvoFLower = 不共存之進化招式。招式 {0} 比其他招式 {1} 習得等級低。
LMoveFDefault_0 = 於第{0}世代之默認招式。
LMoveFExpect_0 = 應該是該招式: {0}。
LMoveFExpectSingle_0 = 應該是該招式: {0}。
LMoveFLevelUp_0 = 於第{0}世代透過升級習得。
LMoveFTMHM_0 = 於第{0}世代透過「招式學習器/秘傳學習器」習得。
LMoveFTutor_0 = 於第{0}世代透過招式教學習得。
LMoveKeldeoMismatch = 凱路迪歐之現時招式與當前形態不匹配。
LMoveNincada = 僅能擁有一個鐵面忍者之招式。
LMoveNincadaEvo = 通過土居忍士進化為鐵面忍者習得。
LMoveNincadaEvoF_0 = 通過土居忍士於第{0}世代進化為鐵面忍者習得。
LMovePPExpectHealed_0 = Move {0} PP is below the amount expected.
LMovePPTooHigh_0 = 招式 {0} PP 高於允許值。
LMovePPUpsTooHigh_0 = 招式 {0} PP 高於允許值。
LMoveRelearnDexNav = 非正確忍足招式。
LMoveRelearnEgg = 基本遺傳招式。
LMoveRelearnEggMissing = 缺失基本遺傳招式。
LMoveRelearnFExpect_0 = 應為以下可回憶招式: {0} ({1})。
LMoveRelearnFMiss_0 = 缺失可回憶招式: {0}。
LMoveRelearnInvalid = 非正確回憶招式。
LMoveRelearnNone = 應該沒有回憶招式。
LMoveRelearnUnderground = 非地下大洞窟預期之蛋招式。
LMoveShopAlphaMoveShouldBeMastered = 頭目技能應標記爲精通。
LMoveShopAlphaMoveShouldBeOther = 此頭目遇見方式未能與該頭目招式匹配。
LMoveShopAlphaMoveShouldBeZero = 僅頭目可擁有頭目招式池。
LMoveShopMasterInvalid_0 = 不能設置此招式為精通「 {0} 」: 此招式不允許精通。
LMoveShopMasterNotLearned_0 = 不能設置此招式為精通「 {0} 」: 不可能習得該升級招式。
LMoveShopPurchaseInvalid_0 = 無法從招式商店中習得 「 {0} 」招式。
LMoveSourceDefault = 默認招式。
LMoveSourceDuplicate = 招式重複。
LMoveSourceEgg = 遺傳招式。
LMoveSourceEggEvent = 神秘禮物配信蛋之招式。
LMoveSourceEmpty = 空招式。
LMoveSourceInvalid = 招式不合法。
LMoveSourceInvalidSketch = 招式不合法 (寫生)。
LMoveSourceLevelUp = 透過升級習得。
LMoveSourceRelearn = 可回憶招式。
LMoveSourceShared = 共用之不可回憶招式。
LMoveSourceSharedF = 共用之{0}代不可回憶招式。
LMoveSourceSpecial = 特殊不可回憶招式。
LMoveSourceTMHM = 透過「招式學習器/秘傳學習器」習得。
LMoveSourceTR = 意外之招式記錄標記: {0}。
LMoveSourceTutor = 通過招式教學習得。
LNickFlagEggNo = 蛋名字不能修改。
LNickFlagEggYes = 蛋必須擁有昵稱。
LNickInvalidChar = 無法給寶可夢取中文昵稱。
LNickLengthLong = 昵稱太長。
LNickLengthShort = 昵稱為空。
LNickMatchLanguage = 昵稱與種類名匹配。
LNickMatchLanguageEgg = 蛋名稱與語言匹配。
LNickMatchLanguageEggFail = 蛋名稱與語言不匹配。
LNickMatchLanguageFail = 昵稱與種類名不匹配。
LNickMatchLanguageFlag = 昵稱被標記,與種類名匹配。
LNickMatchNoOthers = 昵稱不與另一種類名匹配。
LNickMatchNoOthersFail = 昵稱與另一寶可夢種類名匹配 (+language)。
LOT_IDEqual = 十六位元表ID(TID16)及十六位元隱ID(SID16)相等。
LOT_IDInvalid = 表ID及隱ID組合不可能於游戲中獲得。
LOT_IDs0 = 十六位元表ID(TID16)與十六位元隱ID(SID16)為 0。
LOT_SID0 = 十六位元隱ID(SID16)為 0。
LOT_SID0Invalid = 十六位元隱ID(SID16)應為 0。
LOT_TID0 = 十六位元表ID(TID16)為 0。
LOTLanguage = 語言ID應為 {0}, 而不是 {1}。
LOTLong = 初訓家名字過長。
LOTShort = 初訓家名字過短。
LOTSuspicious = 可疑之初訓家信息。
LPIDEncryptWurmple = 刺尾蟲之進化形態與加密常量不匹配。
LPIDEncryptZero = 未設置加密常量。
LPIDEqualsEC = 加密常量與 PID 相同。
LPIDGenderMatch = 性別與 PID 匹配。
LPIDGenderMismatch = 性別與 PID 記載值不匹配。
LPIDNatureMatch = 性格與 PID 記載值匹配。
LPIDNatureMismatch = 性格與 PID 記載值不匹配。
LPIDTypeMismatch = 遇見類型與 PID 記載值不匹配。
LPIDZero = 未設置 PID 。
LPokerusDaysTooHigh_0 = 寶可病毒剩餘天數過長; 應 <= {0}。
LPokerusStrainUnobtainable_0 = 寶可病毒種類 {0} 不可獲得。
LRibbonAllValid = 所有獎章合法。
LRibbonEgg = 蛋不能獲取獎章。
LRibbonFInvalid_0 = 不合法獎章:
LRibbonFMissing_0 = 缺失獎章:
LRibbonMarkingAffixedF_0 = 無效之獎章/證章: {0}。
LRibbonMarkingFInvalid_0 = 無效證章: {0}。
LStatAlphaInvalid = 頭目標識不合法。
LStatBattleVersionInvalid = 對戰版本不在期望範圍內。
LStatDynamaxInvalid = 極巨化等級不在預期範圍內。
LStatGigantamaxInvalid = 超極巨標識不匹配。
LStatGigantamaxValid = 超極巨標識已被極巨湯修改。
LStatIncorrectCP = 計算之 CP 值與存儲值不匹配。
LStatIncorrectHeight = 計算之高度與存儲值不匹配。
LStatIncorrectHeightCopy = 複製之高度與原值不匹配。
LStatIncorrectHeightValue = 高度與期望值不匹配。
LStatIncorrectWeight = 計算之重量與存儲值不匹配。
LStatIncorrectWeightValue = 體重與期望值不匹配。
LStatInvalidHeightWeight = 此身高或體重於統計學意義上不可獲得。
LStatNatureInvalid = 薄荷修正之性格表現不在期望範圍內。
LStatNobleInvalid = 王標識不合法。
LStoredSourceEgg = Egg must be in Box or Party.
LStoredSourceInvalid_0 = Invalid Stored Source: {0}
LSuperComplete = 超級訓練完成標識不匹配。
LSuperDistro = 神秘禮物配信超級訓練任務未發佈。
LSuperEgg = 不能對蛋進行超級訓練。
LSuperNoComplete = 當前出身游戲不能有超級訓練完成之標記。
LSuperNoUnlocked = 當前出身游戲不能有超級訓練解鎖之標記。
LSuperUnavailable = 所達遊戲版本不能進行超級訓練。
LSuperUnused = 未使用之超級訓練旗標被標識。
LTeraTypeIncorrect = 太晶屬性與期望值不匹配。
LTeraTypeMismatch = 太晶屬性無法與寶可夢本身任一屬性相匹配。
LTradeNotAvailable = 該遇見方式寶可夢不可被交換至現時持有之訓練家手上。
LTrainerIDNoSeed = Trainer ID is not obtainable from any RNG seed.
LTransferBad = 該寶可夢不正確地由前代游戲中傳送而來。
LTransferCurrentHandlerInvalid = 不合法之現時持有人資訊,儲存資料訓練家信息應是其他值。
LTransferEgg = 不能跨世代傳送蛋。
LTransferEggLocationTransporter = 不合法之遇見地點, 應該是虛擬傳送。
LTransferEggMetLevel = 對於寶可傳送不合法之遇見等級。
LTransferEggVersion = Can't transfer Eggs to this game.
LTransferFlagIllegal = 游戲中被標記爲非法 (可濫用之Bug)。
LTransferHTFlagRequired = 現任處理教練不能是原教練。
LTransferHTMismatchGender = Handling trainer does not match the expected trainer gender.
LTransferHTMismatchLanguage = 現時持有人與期望語言不匹配。
LTransferHTMismatchName = 現時持有人與期望名字不匹配。
LTransferMet = 不合法遇見地點,應該為寶可傳送或王冠。
LTransferMetLocation = 傳送遇見地點不合法。
LTransferMove = 不相容之虛擬傳送招式。
LTransferMoveG4HM = 需要清除招式「濃霧」與「潮旋」。兩者於傳到5代以前必須被移除。
LTransferMoveHM = 第{0}世代秘傳學習器(秘傳學習器招式)。應於傳至第{1}世代前被移除。
LTransferNature = 對於寶可傳送不合法之性格。
LTransferNotPossible = 無法將現時寶可夢檔格式轉換爲源寶可夢檔格式。
LTransferObedienceLevel = 可指揮等級不合法。
LTransferOriginFInvalid0_1 = 「 {0} 」來源之寶可夢,不能含有於「 ({1}) 」中之遊戲記錄。
LTransferPIDECBitFlip = PID應與加密常量相同[首位須反轉]
LTransferPIDECEquals = PID應與加密常量相同
LTransferPIDECXor = 加密常量與異色 PID 之 XOR 值匹配。
LTransferTrackerMissing = Pokémon HOME 傳輸跟蹤碼資訊丟失。
LTransferTrackerShouldBeZero = Pokémon HOME 傳輸跟蹤碼資訊應置 0。
LTrashBytesExpected = Expected Trash Bytes.
LTrashBytesExpected_0 = Expected Trash Bytes: {0}
LTrashBytesMismatchInitial = Expected initial trash bytes to match the encounter.
LTrashBytesMissingTerminator = Final terminator missing.
LTrashBytesShouldBeEmpty = Trash Bytes should be cleared.
LTrashBytesUnexpected = Unexpected Trash Bytes.

Some files were not shown because too many files have changed in this diff Show More