mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 06:34:19 +00:00
Minor clean
StringBuilder.Append has some fancy interpolation handling in the latest NET8 so it's more clean than multiple append calls.
This commit is contained in:
parent
0ffb256052
commit
f6bcc8a216
29 changed files with 216 additions and 221 deletions
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using System.Text;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
|
@ -55,10 +54,10 @@ public static class QRMessageUtil
|
|||
/// <returns>QR Message</returns>
|
||||
public static string GetMessage(ReadOnlySpan<byte> payload)
|
||||
{
|
||||
var sb = new StringBuilder(payload.Length);
|
||||
foreach (var b in payload)
|
||||
sb.Append((char)b);
|
||||
return sb.ToString();
|
||||
Span<char> result = stackalloc char[payload.Length];
|
||||
for (int i = 0; i < payload.Length; i++)
|
||||
result[i] = (char)payload[i];
|
||||
return new string(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -25,7 +25,7 @@ public readonly record struct MoveLearnInfo(LearnMethod Method, LearnEnvironment
|
|||
sb.Append(Environment).Append('-');
|
||||
sb.Append(localizedMethod);
|
||||
if (Method is LevelUp)
|
||||
sb.Append(" @ lv").Append(Argument);
|
||||
sb.Append($" @ lv{Argument}");
|
||||
}
|
||||
|
||||
private string GetLocalizedMethod() => Method switch
|
||||
|
|
|
@ -52,10 +52,9 @@ public readonly record struct NPCLock
|
|||
sb.Append(" (Shadow)");
|
||||
if (Seen)
|
||||
sb.Append(" [Seen]");
|
||||
sb.Append(" - ");
|
||||
sb.Append("Nature: ").Append((Nature)Nature);
|
||||
sb.Append($" - Nature: {(Nature)Nature}");
|
||||
if (Gender != 2)
|
||||
sb.Append(", ").Append("Gender: ").Append(Gender);
|
||||
sb.Append($", Gender: {Gender}");
|
||||
return sb.ToString();
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -124,10 +124,6 @@ public static class GenerateMethodK
|
|||
|
||||
public static uint GetPIDRegular(uint a, uint b) => b << 16 | a;
|
||||
|
||||
private static void SetPIDIVSequential(PK4 pk, uint pid, uint rand)
|
||||
{
|
||||
}
|
||||
|
||||
private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria)
|
||||
{
|
||||
uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10;
|
||||
|
|
|
@ -352,4 +352,3 @@ public enum GiftSubType4 : byte
|
|||
Accessory = 2,
|
||||
Backdrop = 3,
|
||||
}
|
||||
|
||||
|
|
|
@ -705,7 +705,7 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data),
|
|||
return IsMatchLocationExact(pk) || IsMatchLocationRemapped(pk);
|
||||
}
|
||||
|
||||
private bool IsMatchLocationExact(PKM pk) => pk.MetLocation == this.Location;
|
||||
private bool IsMatchLocationExact(PKM pk) => pk.MetLocation == Location;
|
||||
|
||||
private bool IsMatchLocationRemapped(PKM pk)
|
||||
{
|
||||
|
@ -713,7 +713,7 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data),
|
|||
var version = pk.Version;
|
||||
if (pk.Context == EntityContext.Gen8)
|
||||
return LocationsHOME.IsValidMetBDSP(met, version);
|
||||
return LocationsHOME.GetMetSWSH(this.Location, version) == met;
|
||||
return LocationsHOME.GetMetSWSH(Location, version) == met;
|
||||
}
|
||||
|
||||
protected override bool IsMatchDeferred(PKM pk) => false;
|
||||
|
|
|
@ -191,13 +191,13 @@ public static class StringFont8b
|
|||
'\uFB30', '\uFB31', '\uFB32', '\uFB33', '\uFB34', '\uFB35', '\uFB36', '\uFB38', '\uFB39', '\uFB3A', '\uFB3B', '\uFB3C', '\uFB3E',
|
||||
'\uFB40', '\uFB41', '\uFB43', '\uFB44', '\uFB46', '\uFB47', '\uFB48', '\uFB49', '\uFB4A', '\uFB4B', '\uFB4C', '\uFB4D', '\uFB4E', '\uFB4F',
|
||||
'\uFE20', '\uFE21', '\uFE22', '\uFE23',
|
||||
'\uFFFC'
|
||||
'\uFFFC',
|
||||
];
|
||||
|
||||
public static ReadOnlySpan<char> DefinedCHSExt => [
|
||||
'\u0020', '\u002D', '\u003F', '\u0067', '\u00AA', '\u00B7', '\u00E9',
|
||||
'\u2013', '\u2018', '\u2019', '\u201C', '\u201D', '\u201E', '\u2026', '\u20BD', '\u21D2', '\u21D4', '\u2200', '\u2282', '\u2283',
|
||||
'\u25A0', '\u25BC', '\u25BD', '\u25CF', '\u2605', '\u2661', '\u2665', '\u266A', '\u266D',
|
||||
'\u300A', '\u300B', '\u300C', '\u300D', '\u300E', '\u300F', '\u3010', '\u3011', '\u30FB', '\uFF08', '\uFF09', '\uFF65'
|
||||
'\u300A', '\u300B', '\u300C', '\u300D', '\u300E', '\u300F', '\u3010', '\u3011', '\u30FB', '\uFF08', '\uFF09', '\uFF65',
|
||||
];
|
||||
}
|
||||
|
|
|
@ -105,9 +105,8 @@ public static class TrainerInfoExtensions
|
|||
|
||||
if (tr.Version != pk.Version)
|
||||
{
|
||||
// PK9 does not store version for Picnic eggs.
|
||||
if (pk is PK9 { Version: 0 }) { }
|
||||
else { return false; }
|
||||
if (!IsVersionlessState(pk))
|
||||
return false;
|
||||
}
|
||||
|
||||
Span<char> ot = stackalloc char[pk.MaxStringLengthTrainer];
|
||||
|
@ -119,6 +118,14 @@ public static class TrainerInfoExtensions
|
|||
return true;
|
||||
}
|
||||
|
||||
private static bool IsVersionlessState(PKM pk)
|
||||
{
|
||||
// PK9 does not store version for Picnic eggs.
|
||||
if (pk is PK9 { Version: 0 }) // IsEgg is already true for all calls
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsMatchVersion(ITrainerInfo tr, PKM pk)
|
||||
{
|
||||
if (tr.Version == pk.Version)
|
||||
|
|
|
@ -119,15 +119,15 @@ public static class SCBlockUtil
|
|||
public static string GetBlockSummary(SCBlock b)
|
||||
{
|
||||
var sb = new StringBuilder(64);
|
||||
sb.Append("Key: ").AppendFormat("{0:X8}", b.Key).AppendLine();
|
||||
sb.Append("Type: ").Append(b.Type).AppendLine();
|
||||
sb.AppendLine($"Key: {b.Key:X8}");
|
||||
sb.AppendLine($"Type: {b.Type}");
|
||||
if (b.Data.Length != 0)
|
||||
sb.Append("Length: ").AppendFormat("{0:X8}", b.Data.Length).AppendLine();
|
||||
sb.AppendLine($"Length: {b.Data.Length:X8}");
|
||||
|
||||
if (b.SubType != 0)
|
||||
sb.Append("SubType: ").Append(b.SubType).AppendLine();
|
||||
sb.AppendLine($"SubType: {b.SubType}");
|
||||
else if (b.HasValue())
|
||||
sb.Append("Value: ").Append(b.GetValue()).AppendLine();
|
||||
sb.AppendLine($"Value: {b.GetValue()}");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -243,7 +243,6 @@ public abstract class SAV4 : SaveFile, IEventFlag37, IDaycareStorage, IDaycareRa
|
|||
protected int OFS_Record = int.MinValue;
|
||||
public Record4 Records => new(this, Data.AsMemory(OFS_Record, Record4.GetSize(this)));
|
||||
|
||||
|
||||
// Storage
|
||||
public override int PartyCount
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@ public sealed class SAV5B2W2 : SAV5, ISaveBlock5B2W2
|
|||
public SaveBlockAccessor5B2W2 Blocks { get; }
|
||||
protected override SAV5B2W2 CloneInternal() => new((byte[]) Data.Clone());
|
||||
public override int MaxItemID => Legal.MaxItemID_5_B2W2;
|
||||
|
||||
|
||||
public override IReadOnlyList<BlockInfo> AllBlocks => Blocks.BlockInfo;
|
||||
public override MyItem Items => Blocks.Items;
|
||||
public override Zukan5 Zukan => Blocks.Zukan;
|
||||
|
|
|
@ -136,7 +136,7 @@ public enum DecorationCategory3 : byte
|
|||
Mat,
|
||||
Poster,
|
||||
Doll,
|
||||
Cushion
|
||||
Cushion,
|
||||
}
|
||||
|
||||
public static class DecorationInfo
|
||||
|
|
|
@ -45,7 +45,7 @@ public sealed class SecretBase3PKM : ISpeciesForm
|
|||
{
|
||||
sb.Append($"{Species:000} - {g.Species[Species]}");
|
||||
if (HeldItem != 0)
|
||||
sb.Append(" @ ").Append(g.Item[HeldItem]);
|
||||
sb.Append($" @ {g.Item[HeldItem]}");
|
||||
sb.AppendLine();
|
||||
|
||||
var moveNames = g.Move;
|
||||
|
|
|
@ -17,9 +17,9 @@ public sealed class Record4(SAV4 SAV, Memory<byte> raw) : SaveBlock<SAV4>(SAV, r
|
|||
{
|
||||
public static int GetSize(SAV4 SAV) => SAV switch
|
||||
{
|
||||
SAV4DP => Record32DP * sizeof(uint) + Record16 * sizeof(ushort),
|
||||
SAV4Pt => Record32Pt * sizeof(uint) + Record16 * sizeof(ushort) + 3 * sizeof(ushort),
|
||||
SAV4HGSS => Record32HGSS * sizeof(uint) + Record16 * sizeof(ushort) + 3 * sizeof(ushort),
|
||||
SAV4DP => (Record32DP * sizeof(uint)) +(Record16 * sizeof(ushort)),
|
||||
SAV4Pt => (Record32Pt * sizeof(uint)) +(Record16 * sizeof(ushort)) + (3 * sizeof(ushort)),
|
||||
SAV4HGSS => (Record32HGSS * sizeof(uint)) +(Record16 * sizeof(ushort)) + (3 * sizeof(ushort)),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(SAV)),
|
||||
};
|
||||
|
||||
|
@ -70,7 +70,7 @@ public sealed class Record4(SAV4 SAV, Memory<byte> raw) : SaveBlock<SAV4>(SAV, r
|
|||
/// </remarks>
|
||||
public uint CryptoSeed
|
||||
{
|
||||
get => (SAV is SAV4DP) ? (ushort)0 : ReadUInt32LittleEndian(Data[^4..]);
|
||||
get => (SAV is SAV4DP) ? 0 : ReadUInt32LittleEndian(Data[^4..]);
|
||||
set { if (SAV is not SAV4DP) WriteUInt32LittleEndian(Data[^4..], value); }
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ public sealed class Record4(SAV4 SAV, Memory<byte> raw) : SaveBlock<SAV4>(SAV, r
|
|||
{
|
||||
if (SAV is SAV4DP || IsDecrypted == state) // DP does not encrypt records
|
||||
return;
|
||||
if (IsDecrypted && state == false)
|
||||
if (IsDecrypted && !state)
|
||||
RefreshChecksum(); // refresh only on encrypt
|
||||
PokeCrypto.CryptArray(CryptoData, CryptoSeed);
|
||||
IsDecrypted = state;
|
||||
|
@ -175,14 +175,14 @@ public sealed class Record4(SAV4 SAV, Memory<byte> raw) : SaveBlock<SAV4>(SAV, r
|
|||
|
||||
public uint GetRecord32(int index)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, (uint)Record32);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32);
|
||||
EnsureDecrypted();
|
||||
return ReadUInt32LittleEndian(Record32Data[(index * 4)..]);
|
||||
}
|
||||
|
||||
public void SetRecord32(int index, uint value)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual<uint>((uint)index, (uint)Record32);
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32);
|
||||
EnsureDecrypted();
|
||||
WriteUInt32LittleEndian(Record32Data[(index * 4)..], Math.Min(GetMax32(index), value));
|
||||
}
|
||||
|
|
|
@ -221,5 +221,5 @@ public enum MaxRaidOrigin: uint
|
|||
{
|
||||
Galar,
|
||||
IsleOfArmor,
|
||||
CrownTundra
|
||||
CrownTundra,
|
||||
}
|
||||
|
|
|
@ -156,5 +156,5 @@ public enum TeraRaidOrigin : uint
|
|||
{
|
||||
Paldea,
|
||||
Kitakami,
|
||||
BlueberryAcademy
|
||||
BlueberryAcademy,
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ public interface IGeonet
|
|||
/// </summary>
|
||||
/// <param name="country">Country index</param>
|
||||
/// <param name="subregion">Subregion index</param>
|
||||
/// <param name="point">Point status</param>
|
||||
void SetCountrySubregion(byte country, byte subregion, GeonetPoint point);
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -60,7 +60,7 @@ public static class DateUtil
|
|||
value %= SecondsPerDay;
|
||||
sb.Append(new TimeOnly(ticks: value * TimeSpan.TicksPerSecond).ToString("HH:mm:ss"));
|
||||
if (secondsBias >= 0)
|
||||
sb.Append(Environment.NewLine).Append("Date: ").Append(Epoch2000.AddSeconds(value + secondsBias));
|
||||
sb.Append(Environment.NewLine).Append($"Date: {Epoch2000.AddSeconds(value + secondsBias)}");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
|
|
@ -210,11 +210,11 @@ public static class FileUtil
|
|||
/// <param name="data">Binary data</param>
|
||||
/// <param name="pk">Output result</param>
|
||||
/// <param name="ext">Format hint</param>
|
||||
/// <param name="sav">Reference savefile used for PC Binary compatibility checks.</param>
|
||||
/// <param name="sav">Reference save file used for PC Binary compatibility checks.</param>
|
||||
/// <returns>True if file object reference is valid, false if none found.</returns>
|
||||
public static bool TryGetPKM(byte[] data, [NotNullWhen(true)] out PKM? pk, ReadOnlySpan<char> ext, ITrainerInfo? sav = null)
|
||||
{
|
||||
if (ext == ".pgt") // size collision with pk6
|
||||
if (ext.EndsWith("pgt")) // size collision with pk6
|
||||
{
|
||||
pk = null;
|
||||
return false;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using PKHeX.Core;
|
||||
using static System.Buffers.Binary.BinaryPrimitives;
|
||||
using static PKHeX.Core.DecorationCategory3;
|
||||
|
||||
namespace PKHeX.WinForms;
|
||||
|
||||
|
@ -118,7 +116,7 @@ public partial class SAV_Misc3 : Form
|
|||
TB_B1.Text = Math.Min((ushort)9999, j.JoyfulBerriesInRow).ToString();
|
||||
TB_B2.Text = Math.Min(99990, j.JoyfulBerriesScore).ToString();
|
||||
TB_B3.Text = Math.Min((ushort)9999, j.JoyfulBerries5InRow).ToString();
|
||||
TB_BerryPowder.Text = Math.Min((uint)99999, j.BerryPowder).ToString();
|
||||
TB_BerryPowder.Text = Math.Min(99999u, j.BerryPowder).ToString();
|
||||
}
|
||||
|
||||
private void SaveJoyful(IGen3Joyful j)
|
||||
|
|
|
@ -756,7 +756,7 @@ public partial class SAV_Misc4 : Form
|
|||
DGV_Seals.Columns.Add(dgvSlot);
|
||||
DGV_Seals.Columns.Add(dgvCount);
|
||||
|
||||
var count = (int)Seal4.MAX;
|
||||
const int count = (int)Seal4.MAX;
|
||||
DGV_Seals.Rows.Add(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
DGV_Seals.Rows[i].Cells[0].Value = seals[i];
|
||||
|
@ -825,7 +825,7 @@ public partial class SAV_Misc4 : Form
|
|||
DGV_Accessories.Columns.Add(dgvSlot);
|
||||
DGV_Accessories.Columns.Add(dgvCount);
|
||||
|
||||
var count = AccessoryInfo.Count;
|
||||
const int count = AccessoryInfo.Count;
|
||||
DGV_Accessories.Rows.Add(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
DGV_Accessories.Rows[i].Cells[0].Value = accessories[i];
|
||||
|
|
|
@ -21,7 +21,7 @@ public partial class SAV_Raid8 : Form
|
|||
MaxRaidOrigin.Galar => SAV.RaidGalar,
|
||||
MaxRaidOrigin.IsleOfArmor => SAV.RaidArmor,
|
||||
MaxRaidOrigin.CrownTundra => SAV.RaidCrown,
|
||||
_ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Sword and Shield")
|
||||
_ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Sword and Shield"),
|
||||
};
|
||||
CB_Den.Items.AddRange(Enumerable.Range(1, Raids.CountUsed).Select(z => (object)$"Den {z:000}").ToArray());
|
||||
CB_Den.SelectedIndex = 0;
|
||||
|
|
|
@ -156,7 +156,6 @@ public partial class SAV_PokedexSVKitakami : Form
|
|||
if (forms[0].Length == 0)
|
||||
forms[0] = GameInfo.Strings.Types[0];
|
||||
|
||||
this.SuspendLayout();
|
||||
// Clear all CheckedListBoxes
|
||||
var seen = CLB_FormSeen.Items;
|
||||
var obtained = CLB_FormObtained.Items;
|
||||
|
|
|
@ -22,7 +22,7 @@ public partial class SAV_Raid9 : Form
|
|||
TeraRaidOrigin.Paldea => SAV.RaidPaldea,
|
||||
TeraRaidOrigin.Kitakami => SAV.RaidKitakami,
|
||||
TeraRaidOrigin.BlueberryAcademy => SAV.RaidBlueberry,
|
||||
_ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Scarlet and Violet")
|
||||
_ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Scarlet and Violet"),
|
||||
};
|
||||
CB_Raid.Items.AddRange(Enumerable.Range(1, Raids.CountUsed).Select(z => (object)$"Raid {z:000}").ToArray());
|
||||
CB_Raid.SelectedIndex = 0;
|
||||
|
|
|
@ -7,182 +7,181 @@ using System.Windows.Forms;
|
|||
using PKHeX.Core;
|
||||
using PKHeX.WinForms.Controls;
|
||||
|
||||
namespace PKHeX.WinForms
|
||||
namespace PKHeX.WinForms;
|
||||
|
||||
public static class DevUtil
|
||||
{
|
||||
public static class DevUtil
|
||||
public static void AddControl(ToolStripDropDownItem t)
|
||||
{
|
||||
public static void AddControl(ToolStripDropDownItem t)
|
||||
t.DropDownItems.Add(GetTranslationUpdater());
|
||||
}
|
||||
|
||||
private static readonly string[] Languages = ["ja", "fr", "it", "de", "es", "ko", "zh", "zh2"];
|
||||
private static string DefaultLanguage => Main.CurrentLanguage;
|
||||
|
||||
public static bool IsUpdatingTranslations { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Call this to update all translatable resources (Program Messages, Legality Text, Program GUI)
|
||||
/// </summary>
|
||||
private static void UpdateAll()
|
||||
{
|
||||
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Update translation files with current values?"))
|
||||
return;
|
||||
IsUpdatingTranslations = true;
|
||||
DumpStringsLegality();
|
||||
DumpStringsMessage();
|
||||
UpdateTranslations();
|
||||
IsUpdatingTranslations = false;
|
||||
}
|
||||
|
||||
private static ToolStripMenuItem GetTranslationUpdater()
|
||||
{
|
||||
var ti = new ToolStripMenuItem
|
||||
{
|
||||
t.DropDownItems.Add(GetTranslationUpdater());
|
||||
ShortcutKeys = Keys.Control | Keys.Alt | Keys.D,
|
||||
Visible = false,
|
||||
};
|
||||
ti.Click += (_, _) => UpdateAll();
|
||||
return ti;
|
||||
}
|
||||
|
||||
private static void UpdateTranslations()
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
var types = assembly.GetTypes();
|
||||
|
||||
// Trigger a translation then dump all.
|
||||
foreach (var lang in Languages) // get all languages ready to go
|
||||
_ = WinFormsTranslator.GetDictionary(lang);
|
||||
WinFormsTranslator.SetUpdateMode();
|
||||
WinFormsTranslator.LoadSettings<PKHeXSettings>(DefaultLanguage);
|
||||
WinFormsTranslator.LoadEnums(EnumTypesToTranslate, DefaultLanguage);
|
||||
WinFormsTranslator.LoadAllForms(types, LoadBanlist); // populate with every possible control
|
||||
WinFormsTranslator.TranslateControls(GetExtraControls(), DefaultLanguage);
|
||||
var dir = GetResourcePath("PKHeX.WinForms", "Resources", "text");
|
||||
WinFormsTranslator.DumpAll(DefaultLanguage, Banlist, dir); // dump current to file
|
||||
WinFormsTranslator.SetUpdateMode(false);
|
||||
|
||||
// Move translated files from the debug exe loc to their project location
|
||||
var files = Directory.GetFiles(Application.StartupPath);
|
||||
foreach (var f in files)
|
||||
{
|
||||
var fn = Path.GetFileName(f);
|
||||
if (!fn.EndsWith(".txt"))
|
||||
continue;
|
||||
if (!fn.StartsWith("lang_"))
|
||||
continue;
|
||||
|
||||
var loc = Path.Combine(dir, fn);
|
||||
if (File.Exists(loc))
|
||||
File.Delete(loc);
|
||||
File.Move(f, loc, true);
|
||||
}
|
||||
|
||||
private static readonly string[] Languages = ["ja", "fr", "it", "de", "es", "ko", "zh", "zh2"];
|
||||
private static string DefaultLanguage => Main.CurrentLanguage;
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
public static bool IsUpdatingTranslations { get; private set; }
|
||||
private static readonly Type[] EnumTypesToTranslate =
|
||||
[
|
||||
typeof(StatusCondition),
|
||||
typeof(PokeSize),
|
||||
typeof(PokeSizeDetailed),
|
||||
|
||||
/// <summary>
|
||||
/// Call this to update all translatable resources (Program Messages, Legality Text, Program GUI)
|
||||
/// </summary>
|
||||
private static void UpdateAll()
|
||||
typeof(PassPower5),
|
||||
typeof(Funfest5Mission),
|
||||
typeof(OPower6Index),
|
||||
typeof(OPower6FieldType),
|
||||
typeof(OPower6BattleType),
|
||||
typeof(PlayerBattleStyle7),
|
||||
typeof(PlayerSkinColor7),
|
||||
typeof(Stamp7),
|
||||
typeof(FestivalPlazaFacilityColor),
|
||||
];
|
||||
|
||||
private static IEnumerable<Control> GetExtraControls()
|
||||
{
|
||||
foreach (var name in SlotList.GetEnumNames().Distinct())
|
||||
yield return new Label { Name = $"{nameof(Main)}.L_{name}", Text = name };
|
||||
}
|
||||
|
||||
private static readonly string[] LoadBanlist =
|
||||
[
|
||||
nameof(SplashScreen),
|
||||
nameof(PokePreview),
|
||||
];
|
||||
|
||||
private static readonly string[] Banlist =
|
||||
[
|
||||
"Gender=", // editor gender labels
|
||||
"BTN_Shinytize", // ☆
|
||||
"Hidden_", // Hidden controls
|
||||
"CAL_", // calendar controls now expose Text, don't care.
|
||||
".Count", // enum count
|
||||
$"{nameof(Main)}.L_SizeH", // height rating
|
||||
$"{nameof(Main)}.L_SizeW", // weight rating
|
||||
$"{nameof(Main)}.L_SizeS", // scale rating
|
||||
$"{nameof(Main)}.B_Box", // << and >> arrows
|
||||
$"{nameof(Main)}.L_Characteristic=", // Characterstic (dynamic)
|
||||
$"{nameof(Main)}.L_Potential", // ★☆☆☆ IV judge evaluation
|
||||
$"{nameof(SAV_HoneyTree)}.L_Tree0", // dynamic, don't bother
|
||||
$"{nameof(SAV_Misc3)}.BTN_Symbol", // symbols should stay as their current character
|
||||
$"{nameof(SAV_GameSelect)}.L_Prompt", // prompt text (dynamic)
|
||||
$"{nameof(SAV_BlockDump8)}.L_BlockName", // Block name (dynamic)
|
||||
$"{nameof(SAV_PokedexResearchEditorLA)}.L_", // Dynamic label
|
||||
$"{nameof(SAV_OPower)}.L_", // Dynamic label
|
||||
];
|
||||
|
||||
private static void DumpStringsMessage() => DumpStrings(typeof(MessageStrings), false, "PKHeX.Core", "Resources", "text", "program");
|
||||
private static void DumpStringsLegality() => DumpStrings(typeof(LegalityCheckStrings), true, "PKHeX.Core", "Resources", "legality", "checks");
|
||||
|
||||
private static void DumpStrings(Type t, bool sorted, params string[] rel)
|
||||
{
|
||||
var dir = GetResourcePath(rel);
|
||||
DumpStrings(t, sorted, DefaultLanguage, dir);
|
||||
foreach (var lang in Languages)
|
||||
DumpStrings(t, sorted, lang, dir);
|
||||
}
|
||||
|
||||
private static void DumpStrings(Type t, bool sorted, string lang, string dir)
|
||||
{
|
||||
LocalizationUtil.SetLocalization(t, lang);
|
||||
var entries = LocalizationUtil.GetLocalization(t);
|
||||
IEnumerable<string> export = entries.OrderBy(GetName); // sorted lines
|
||||
|
||||
if (!sorted)
|
||||
export = entries;
|
||||
|
||||
var location = GetFileLocationInText(t.Name, dir, lang);
|
||||
File.WriteAllLines(location, export);
|
||||
LocalizationUtil.SetLocalization(t, DefaultLanguage);
|
||||
|
||||
static string GetName(string line)
|
||||
{
|
||||
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Update translation files with current values?"))
|
||||
return;
|
||||
IsUpdatingTranslations = true;
|
||||
DumpStringsLegality();
|
||||
DumpStringsMessage();
|
||||
UpdateTranslations();
|
||||
IsUpdatingTranslations = false;
|
||||
var index = line.IndexOf('=');
|
||||
if (index == -1)
|
||||
return line;
|
||||
return line[..index];
|
||||
}
|
||||
}
|
||||
|
||||
private static ToolStripMenuItem GetTranslationUpdater()
|
||||
private static string GetFileLocationInText(string fileType, string dir, string lang)
|
||||
{
|
||||
var fn = $"{fileType}_{lang}.txt";
|
||||
return Path.Combine(dir, fn);
|
||||
}
|
||||
|
||||
private static string GetResourcePath(params string[] subdir)
|
||||
{
|
||||
// Starting from the executable path, crawl upwards until we get to the repository/sln root
|
||||
const string repo = "PKHeX";
|
||||
var path = Application.StartupPath;
|
||||
while (true)
|
||||
{
|
||||
var ti = new ToolStripMenuItem
|
||||
{
|
||||
ShortcutKeys = Keys.Control | Keys.Alt | Keys.D,
|
||||
Visible = false,
|
||||
};
|
||||
ti.Click += (_, _) => UpdateAll();
|
||||
return ti;
|
||||
}
|
||||
|
||||
private static void UpdateTranslations()
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
var types = assembly.GetTypes();
|
||||
|
||||
// Trigger a translation then dump all.
|
||||
foreach (var lang in Languages) // get all languages ready to go
|
||||
_ = WinFormsTranslator.GetDictionary(lang);
|
||||
WinFormsTranslator.SetUpdateMode();
|
||||
WinFormsTranslator.LoadSettings<PKHeXSettings>(DefaultLanguage);
|
||||
WinFormsTranslator.LoadEnums(EnumTypesToTranslate, DefaultLanguage);
|
||||
WinFormsTranslator.LoadAllForms(types, LoadBanlist); // populate with every possible control
|
||||
WinFormsTranslator.TranslateControls(GetExtraControls(), DefaultLanguage);
|
||||
var dir = GetResourcePath("PKHeX.WinForms", "Resources", "text");
|
||||
WinFormsTranslator.DumpAll(DefaultLanguage, Banlist, dir); // dump current to file
|
||||
WinFormsTranslator.SetUpdateMode(false);
|
||||
|
||||
// Move translated files from the debug exe loc to their project location
|
||||
var files = Directory.GetFiles(Application.StartupPath);
|
||||
foreach (var f in files)
|
||||
{
|
||||
var fn = Path.GetFileName(f);
|
||||
if (!fn.EndsWith(".txt"))
|
||||
continue;
|
||||
if (!fn.StartsWith("lang_"))
|
||||
continue;
|
||||
|
||||
var loc = Path.Combine(dir, fn);
|
||||
if (File.Exists(loc))
|
||||
File.Delete(loc);
|
||||
File.Move(f, loc, true);
|
||||
}
|
||||
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
private static readonly Type[] EnumTypesToTranslate =
|
||||
[
|
||||
typeof(StatusCondition),
|
||||
typeof(PokeSize),
|
||||
typeof(PokeSizeDetailed),
|
||||
|
||||
typeof(PassPower5),
|
||||
typeof(Funfest5Mission),
|
||||
typeof(OPower6Index),
|
||||
typeof(OPower6FieldType),
|
||||
typeof(OPower6BattleType),
|
||||
typeof(PlayerBattleStyle7),
|
||||
typeof(PlayerSkinColor7),
|
||||
typeof(Stamp7),
|
||||
typeof(FestivalPlazaFacilityColor),
|
||||
];
|
||||
|
||||
private static IEnumerable<Control> GetExtraControls()
|
||||
{
|
||||
foreach (var name in SlotList.GetEnumNames().Distinct())
|
||||
yield return new Label { Name = $"{nameof(Main)}.L_{name}", Text = name };
|
||||
}
|
||||
|
||||
private static readonly string[] LoadBanlist =
|
||||
[
|
||||
nameof(SplashScreen),
|
||||
nameof(PokePreview),
|
||||
];
|
||||
|
||||
private static readonly string[] Banlist =
|
||||
[
|
||||
"Gender=", // editor gender labels
|
||||
"BTN_Shinytize", // ☆
|
||||
"Hidden_", // Hidden controls
|
||||
"CAL_", // calendar controls now expose Text, don't care.
|
||||
".Count", // enum count
|
||||
$"{nameof(Main)}.L_SizeH", // height rating
|
||||
$"{nameof(Main)}.L_SizeW", // weight rating
|
||||
$"{nameof(Main)}.L_SizeS", // scale rating
|
||||
$"{nameof(Main)}.B_Box", // << and >> arrows
|
||||
$"{nameof(Main)}.L_Characteristic=", // Characterstic (dynamic)
|
||||
$"{nameof(Main)}.L_Potential", // ★☆☆☆ IV judge evaluation
|
||||
$"{nameof(SAV_HoneyTree)}.L_Tree0", // dynamic, don't bother
|
||||
$"{nameof(SAV_Misc3)}.BTN_Symbol", // symbols should stay as their current character
|
||||
$"{nameof(SAV_GameSelect)}.L_Prompt", // prompt text (dynamic)
|
||||
$"{nameof(SAV_BlockDump8)}.L_BlockName", // Block name (dynamic)
|
||||
$"{nameof(SAV_PokedexResearchEditorLA)}.L_", // Dynamic label
|
||||
$"{nameof(SAV_OPower)}.L_", // Dynamic label
|
||||
];
|
||||
|
||||
private static void DumpStringsMessage() => DumpStrings(typeof(MessageStrings), false, "PKHeX.Core", "Resources", "text", "program");
|
||||
private static void DumpStringsLegality() => DumpStrings(typeof(LegalityCheckStrings), true, "PKHeX.Core", "Resources", "legality", "checks");
|
||||
|
||||
private static void DumpStrings(Type t, bool sorted, params string[] rel)
|
||||
{
|
||||
var dir = GetResourcePath(rel);
|
||||
DumpStrings(t, sorted, DefaultLanguage, dir);
|
||||
foreach (var lang in Languages)
|
||||
DumpStrings(t, sorted, lang, dir);
|
||||
}
|
||||
|
||||
private static void DumpStrings(Type t, bool sorted, string lang, string dir)
|
||||
{
|
||||
LocalizationUtil.SetLocalization(t, lang);
|
||||
var entries = LocalizationUtil.GetLocalization(t);
|
||||
IEnumerable<string> export = entries.OrderBy(GetName); // sorted lines
|
||||
|
||||
if (!sorted)
|
||||
export = entries;
|
||||
|
||||
var location = GetFileLocationInText(t.Name, dir, lang);
|
||||
File.WriteAllLines(location, export);
|
||||
LocalizationUtil.SetLocalization(t, DefaultLanguage);
|
||||
|
||||
static string GetName(string line)
|
||||
{
|
||||
var index = line.IndexOf('=');
|
||||
if (index == -1)
|
||||
return line;
|
||||
return line[..index];
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetFileLocationInText(string fileType, string dir, string lang)
|
||||
{
|
||||
var fn = $"{fileType}_{lang}.txt";
|
||||
return Path.Combine(dir, fn);
|
||||
}
|
||||
|
||||
private static string GetResourcePath(params string[] subdir)
|
||||
{
|
||||
// Starting from the executable path, crawl upwards until we get to the repository/sln root
|
||||
const string repo = "PKHeX";
|
||||
var path = Application.StartupPath;
|
||||
while (true)
|
||||
{
|
||||
var parent = Directory.GetParent(path) ?? throw new DirectoryNotFoundException(path);
|
||||
path = parent.FullName;
|
||||
if (path.EndsWith(repo))
|
||||
return Path.Combine(path, Path.Combine(subdir));
|
||||
}
|
||||
var parent = Directory.GetParent(path) ?? throw new DirectoryNotFoundException(path);
|
||||
path = parent.FullName;
|
||||
if (path.EndsWith(repo))
|
||||
return Path.Combine(path, Path.Combine(subdir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ public static class WinFormsUtil
|
|||
{
|
||||
var sb = new StringBuilder(128);
|
||||
foreach (var type in extensions)
|
||||
sb.Append("*.").Append(type).Append(';');
|
||||
sb.Append($"*.{type};");
|
||||
sb.Append("*.pk");
|
||||
|
||||
string supported = sb.ToString();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ public static class PIDTests
|
|||
[0xF2AC8419, 0xADA208E3, 0xDB3A0BA6, 0x5EEF1076],
|
||||
[0x9D28899D, 0xA3ECC9F0, 0x606EC6F0, 0x451FAE3C],
|
||||
},
|
||||
Delcatty
|
||||
Delcatty,
|
||||
];
|
||||
yield return
|
||||
[
|
||||
|
@ -145,7 +145,7 @@ public static class PIDTests
|
|||
[0xC7315E32, 0x76566AA1, 0xC0CE436E, 0x98C45DA8, 0x9D1BDC4A],
|
||||
[0xB687F0AF, 0xC01DB6C6, 0xAD6DEC75, 0xDB041314, 0x0D949325],
|
||||
},
|
||||
Butterfree
|
||||
Butterfree,
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ public class StringTests
|
|||
|
||||
private static string Hex(ReadOnlySpan<byte> outdata)
|
||||
{
|
||||
var sb = new System.Text.StringBuilder(outdata.Length);
|
||||
var sb = new System.Text.StringBuilder(outdata.Length*3);
|
||||
foreach (var b in outdata)
|
||||
sb.Append(b.ToString("X2")).Append(' ');
|
||||
sb.Append($"{b:X2} ");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue