From e1449fc7b7ebe85f302a3988d8410da2086bd66e Mon Sep 17 00:00:00 2001 From: MayNL Date: Mon, 29 Jun 2026 14:04:07 -0400 Subject: [PATCH] CustomSkinEditor now displays loc keys and translated names --- PCK-Studio/Controls/Editor/PckEditor.cs | 11 ++- .../Extensions/PckAssetExtensions.cs | 76 +++++++++++++++++-- PckStudio.Core/Skin/SkinMetaData.cs | 1 + 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/PCK-Studio/Controls/Editor/PckEditor.cs b/PCK-Studio/Controls/Editor/PckEditor.cs index ac728bd1..14879a4c 100644 --- a/PCK-Studio/Controls/Editor/PckEditor.cs +++ b/PCK-Studio/Controls/Editor/PckEditor.cs @@ -525,7 +525,10 @@ namespace PckStudio.Controls private void HandleSkinFile(PckAsset asset) { - Skin skin = asset.GetSkin(); + LOCFile locFile = null; + TryGetLocFile(out locFile); + + Skin skin = asset.GetSkin(locFile); if (asset.HasParameter("CAPEPATH")) { string capeAssetPath = asset.GetParameter("CAPEPATH"); @@ -537,9 +540,13 @@ namespace PckStudio.Controls ISaveContext saveContext = new DelegatedSaveContext(Settings.Default.AutoSaveChanges, (customSkin) => { - if (!TryGetLocFile(out LOCFile locFile)) + if (locFile == null) Debug.WriteLine("Failed to aquire loc file."); + asset.SetSkin(customSkin, locFile); + + if (locFile != null) + TrySetLocFile(locFile); }); if (skin.Model.AdditionalBoxes.FindAll(box => box.Scale != 0).Count > 0 && EditorValue.File.xmlVersion != 3 && diff --git a/PckStudio.Core/Extensions/PckAssetExtensions.cs b/PckStudio.Core/Extensions/PckAssetExtensions.cs index 52ec775e..4aaef8f9 100644 --- a/PckStudio.Core/Extensions/PckAssetExtensions.cs +++ b/PckStudio.Core/Extensions/PckAssetExtensions.cs @@ -80,23 +80,89 @@ namespace PckStudio.Core.Extensions return skinId; } - public static Skin.Skin GetSkin(this PckAsset asset) + public static Skin.Skin GetSkin(this PckAsset asset, LOCFile localizationFile = null) { if (asset.Type != PckAssetType.SkinFile) throw new InvalidOperationException("Asset is not a skin."); int skinId = asset.GetSkinId(); - string name = asset.GetParameter("DISPLAYNAME"); Image texture = asset.GetTexture(); SkinANIM anim = asset.GetParameter("ANIM", SkinANIM.FromString); SkinGameFlags gameFlags = asset.GetParameter("GAME_FLAGS", SkinGameFlags.FromString); IEnumerable boxes = asset.GetMultipleParameters("BOX").Select(kv => SkinBOX.FromString(kv.Value)); IEnumerable offsets = asset.GetMultipleParameters("OFFSET").Select(kv => SkinPartOffset.FromString(kv.Value)).GroupBy(o => o.Type).Select(g => g.First()); - return new Skin.Skin(name, skinId, texture, anim, gameFlags, boxes, offsets); + + // this is so something is displayed in the custom skin editor when a displayname is missing but does write that name as the DISPLAYNAME when done + bool isDisplayName = true; + string name = ""; + + // prioritize LOC_KEY since DISPLAYNAMEID doesn't even exist in versions after Update Aquatic + if (string.IsNullOrEmpty(name)) + { + string locKey = asset.GetParameter("LOC_KEY"); + + if (!string.IsNullOrEmpty(locKey)) + { + name = locKey; + + if (localizationFile is not null && localizationFile.HasLocEntry(locKey)) + { + try + { + name = localizationFile.GetLocEntry(locKey, "en-EN"); + } + catch + { + name = locKey; + } + + if (string.IsNullOrEmpty(name)) + name = locKey; + } + } + } + + string displaynameID = asset.GetParameter("DISPLAYNAMEID"); + if (!string.IsNullOrEmpty(displaynameID)) + { + name = displaynameID; + + if (localizationFile is not null && localizationFile.HasLocEntry(displaynameID)) + { + try + { + name = localizationFile.GetLocEntry(displaynameID, "en-EN"); + } + catch + { + name = displaynameID; + } + + if (string.IsNullOrEmpty(name)) + name = displaynameID; + } + } + + if (string.IsNullOrEmpty(name)) + { + isDisplayName = true; + + name = asset.GetParameter("DISPLAYNAME"); + + if (string.IsNullOrEmpty(name)) + { + name = Path.GetFileNameWithoutExtension(asset.Filename); + } + } + + Skin.Skin skin = new Skin.Skin(name, skinId, texture, anim, gameFlags, boxes, offsets); + skin.MetaData.IsDisplayName = isDisplayName; + + return skin; } - public static void SetSkin(this PckAsset asset, Skin.Skin skin, LOCFile localizationFile) + public static void SetSkin(this PckAsset asset, Skin.Skin skin, in LOCFile localizationFile) { if (asset.Type != PckAssetType.SkinFile) throw new InvalidOperationException("Asset is not a skin file"); @@ -108,7 +174,7 @@ namespace PckStudio.Core.Extensions // TODO: keep filepath asset.Filename = $"dlcskin{skinId}.png"; - if (!string.IsNullOrEmpty(skin.MetaData.Name)) + if (!string.IsNullOrEmpty(skin.MetaData.Name) && skin.MetaData.IsDisplayName) { asset.SetParameter("DISPLAYNAME", skin.MetaData.Name); diff --git a/PckStudio.Core/Skin/SkinMetaData.cs b/PckStudio.Core/Skin/SkinMetaData.cs index 0077bdc5..bf795f9f 100644 --- a/PckStudio.Core/Skin/SkinMetaData.cs +++ b/PckStudio.Core/Skin/SkinMetaData.cs @@ -4,6 +4,7 @@ { public string Name { get; } public string Theme { get; } + public bool IsDisplayName; public SkinMetaData(string name, string theme) {