mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-22 01:55:10 -05:00
Generation was always more weak; am I paranoid about potential VC3? maybe Better indicates the move source for LGPE exclusive moves, etc.
158 lines
8.1 KiB
C#
158 lines
8.1 KiB
C#
using System;
|
|
using static PKHeX.Core.LegalityCheckResultCode;
|
|
|
|
namespace PKHeX.Core;
|
|
|
|
/// <summary>
|
|
/// Value object that contains the context for localization of legality checks.
|
|
/// </summary>
|
|
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(LegalityCheckResultCode code) => RibbonVerifier.GetMessage(Analysis, Strings.Ribbons, code);
|
|
public string GetStatName(int displayIndex) => GetSafe(Settings.General.StatNames, displayIndex);
|
|
public string GetMoveName(ushort move) => GetSafe(Strings.movelist, move);
|
|
public string GetItemName(ushort item) => GetSafe(Strings.itemlist, item);
|
|
public string GetSpeciesName(ushort species) => GetSafe(Strings.specieslist, species);
|
|
public string GetConsoleRegion3DS(int index) => GetSafe(Strings.console3ds, index);
|
|
public string GetRibbonName(RibbonIndex index) => Strings.Ribbons.GetNameSafe($"Ribbon{index}", out var result) ? result : index.ToString();
|
|
public string GetLanguageName(int index) => GetSafe(Strings.languageNames, index);
|
|
public string GetFormName(ushort species, byte form, EntityContext context) => FormConverter.GetStringFromForm(species, form, Strings, context);
|
|
|
|
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, Settings.Description(chk.Judgement), str);
|
|
}
|
|
|
|
private string GetInternalString(CheckResult chk)
|
|
{
|
|
var code = chk.Result;
|
|
if (code is External)
|
|
return ExternalLegalityCheck.Localize(chk, Settings, Analysis);
|
|
var template = code.GetTemplate(Settings.Lines);
|
|
if (code < FirstWithArgument)
|
|
return template;
|
|
if (code.IsArgument)
|
|
return string.Format(template, chk.Argument);
|
|
if (code.IsArgument2)
|
|
return string.Format(template, chk.Argument, chk.Argument2);
|
|
if (code.IsMove)
|
|
return string.Format(template, GetMoveName(chk.Argument));
|
|
if (code.IsItem)
|
|
return string.Format(template, GetItemName(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 < FirstMemoryWithValue)
|
|
return string.Format(template, GetTrainer(chk.Argument));
|
|
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?
|
|
RibbonsInvalid_0 => string.Format(format, GetRibbonMessage(code)),
|
|
RibbonsMissing_0 => string.Format(format, GetRibbonMessage(code)),
|
|
WordFilterFlaggedPattern_01 => string.Format(format, WordFilter.GetPattern((WordFilterType)chk.Argument, chk.Argument2), (WordFilterType)chk.Argument),
|
|
WordFilterInvalidCharacter_0 => string.Format(format, chk.Argument, 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((RibbonIndex)chk.Argument)),
|
|
RibbonMarkingMissing_0 => string.Format(format, GetRibbonName((RibbonIndex)chk.Argument)),
|
|
RibbonMarkingAffixed_0 => string.Format(format, GetRibbonName((RibbonIndex)chk.Argument)),
|
|
|
|
StoredSlotSourceInvalid_0 => string.Format(format, (StorageSlotSource)chk.Argument),
|
|
HintEvolvesToRareForm_0 => string.Format(format, chk.Argument == 1),
|
|
FormInvalidRangeLEQ_0F => string.Format(format, chk.Argument, Analysis.Entity.Form),
|
|
|
|
OTLanguageShouldBe_0or1 => string.Format(format, GetLanguageName(chk.Argument), GetLanguageName(chk.Argument2), GetLanguageName(Analysis.Entity.Language)),
|
|
G6SuperTrainBagHitsInvalid_012 => string.Format(format, (Analysis.Entity as PK6)?.TrainingBagHits ?? 0, chk.Argument, chk.Argument2),
|
|
|
|
>= MAX => throw new ArgumentOutOfRangeException(nameof(code), code, null),
|
|
};
|
|
|
|
public string FormatMove(in MoveResult move, int index, EntityContext current)
|
|
{
|
|
var result = Format(move, index, Settings.Moves.FormatMove);
|
|
var original = move.Context;
|
|
if (current != original && original != 0)
|
|
result += $" [{original}]";
|
|
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, Settings.Description(move.Judgement), index, move.Summary(this));
|
|
}
|