diff --git a/FFXIV_TexTools/FFXIV_TexTools.csproj b/FFXIV_TexTools/FFXIV_TexTools.csproj index d1d580f8..33ffabe6 100644 --- a/FFXIV_TexTools/FFXIV_TexTools.csproj +++ b/FFXIV_TexTools/FFXIV_TexTools.csproj @@ -23,9 +23,9 @@ FFXIV_TexTools Copyright © 2024 - 3.0.6.1 - 3.0.6.1 - 3.0.6.1 + 3.0.6.2 + 3.0.6.2 + 3.0.6.2 9.0 true @@ -156,6 +156,10 @@ XivStringRaces.Designer.cs Designer + + ResXFileCodeGenerator + XivStrings.Designer.cs + @@ -198,6 +202,11 @@ True UIStrings.resx + + True + True + XivStrings.resx + Code diff --git a/FFXIV_TexTools/Helpers/ModpackUpgraderWrapper.cs b/FFXIV_TexTools/Helpers/ModpackUpgraderWrapper.cs index 7d2bcc70..bb4f41bb 100644 --- a/FFXIV_TexTools/Helpers/ModpackUpgraderWrapper.cs +++ b/FFXIV_TexTools/Helpers/ModpackUpgraderWrapper.cs @@ -22,58 +22,73 @@ public static async Task UpgradeModpackPrompted(bool includePartials = true) InitialDirectory = Path.GetFullPath(Settings.Default.ModPack_Directory), }; + ofd.Multiselect = true; if (ofd.ShowDialog() != System.Windows.Forms.DialogResult.OK) { return; } - var path = ofd.FileName; + + var paths = ofd.FileNames; await mw.LockUi("Upgrading Modpack", "Please Wait...\n\nIf this takes more than 3-5 minutes, please close TexTools and retry with \nOptions => Settings => 'Compress Upgrade Textures' turned off."); try { + var i = 1; + foreach (var path in paths) + { + if(paths.Length > 1) + { + mw._lockProgressController.SetMessage("Updating Mod #" + i + "/" + paths.Length); + } - var data = await xivModdingFramework.Mods.ModpackUpgrader.UpgradeModpack(path, includePartials); + var data = await xivModdingFramework.Mods.ModpackUpgrader.UpgradeModpack(path, includePartials); - if(!data.AnyChanges) - { - FlexibleMessageBox.Show(ViewHelpers.GetWin32Window(MainWindow.GetMainWindow()), - "The upgrader found nothing to upgrade in the modpack.\n\nThis typically means the mod either does not need to be upgraded, must be manually upgraded, or was already upgraded, possibly by another tool (Ex. Penumbra).", - "No Upgrade Needed", - MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } + if (!data.AnyChanges && paths.Length == 1) + { + FlexibleMessageBox.Show(ViewHelpers.GetWin32Window(MainWindow.GetMainWindow()), + "The upgrader found nothing to upgrade in the modpack.\n\nThis typically means the mod either does not need to be upgraded, must be manually upgraded, or was already upgraded, possibly by another tool (Ex. Penumbra).", + "No Upgrade Needed", + MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } - var ext = Path.GetExtension(path); + var ext = Path.GetExtension(path); - var name = Path.GetFileNameWithoutExtension(path); - if (ext == ".json") - { - name = IOUtil.MakePathSafe(data.Data.MetaPage.Name, false); - } + var name = Path.GetFileNameWithoutExtension(path); + if (ext == ".json") + { + name = IOUtil.MakePathSafe(data.Data.MetaPage.Name, false); + } - if (ext != ".ttmp2" && ext != ".pmp") - { - ext = ".pmp"; - } + if (ext != ".ttmp2" && ext != ".pmp") + { + ext = ".pmp"; + } - // Final Save location - var dir = Path.GetDirectoryName(path); - var fName = name + "_dt" + ext; - var sfd = new SaveFileDialog() - { - FileName = fName, - Filter = ViewHelpers.ModpackFileFilter, - InitialDirectory = dir, - }; - if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK) - { - return; + // Final Save location + var dir = Path.GetDirectoryName(path); + var fName = name + "_dt" + ext; + var newPath = Path.GetFullPath(Path.Combine(dir, fName)); + if (paths.Length == 1) + { + var sfd = new SaveFileDialog() + { + FileName = fName, + Filter = ViewHelpers.ModpackFileFilter, + InitialDirectory = dir, + }; + if (sfd.ShowDialog() != System.Windows.Forms.DialogResult.OK) + { + return; + } + newPath = sfd.FileName; + } + + await data.Data.WriteModpack(newPath, true); } - var newPath = sfd.FileName; - await data.Data.WriteModpack(newPath, true); } catch (Exception ex) { diff --git a/FFXIV_TexTools/MainWindow.xaml b/FFXIV_TexTools/MainWindow.xaml index 10d1104a..1dc6d4da 100644 --- a/FFXIV_TexTools/MainWindow.xaml +++ b/FFXIV_TexTools/MainWindow.xaml @@ -110,8 +110,8 @@ - - + + diff --git a/FFXIV_TexTools/MainWindow.xaml.cs b/FFXIV_TexTools/MainWindow.xaml.cs index ec6c697c..f9604238 100644 --- a/FFXIV_TexTools/MainWindow.xaml.cs +++ b/FFXIV_TexTools/MainWindow.xaml.cs @@ -240,7 +240,7 @@ public bool IsUiLocked public IProgress LockProgress { get { return _lockProgress; } } - private ProgressDialogController _lockProgressController ; + internal ProgressDialogController _lockProgressController ; /// /// Fired when the old tree is about to be discarded. diff --git a/FFXIV_TexTools/Models/PenumbraUpgradeStatus.cs b/FFXIV_TexTools/Models/PenumbraUpgradeStatus.cs index 6055bf28..cf458823 100644 --- a/FFXIV_TexTools/Models/PenumbraUpgradeStatus.cs +++ b/FFXIV_TexTools/Models/PenumbraUpgradeStatus.cs @@ -11,10 +11,11 @@ using System.Diagnostics; using xivModdingFramework.Mods; using xivModdingFramework.Exd.FileTypes; +using FFXIV_TexTools.Views.Upgrades; namespace FFXIV_TexTools.Models { - public class PenumbraUpgradeStatus + public class PenumbraUpgradeStatus : ICloneable { [JsonConverter(typeof(StringEnumConverter))] public enum EUpgradeResult @@ -28,7 +29,7 @@ public enum EUpgradeResult public Dictionary Upgrades = new Dictionary(); - public async Task ProcessMod(string baseDir, string targetDir, string mod) + public async Task ProcessMod(string baseDir, string targetDir, string mod, bool compress = true) { var source = Path.GetFullPath(Path.Combine(baseDir, mod)); var target = Path.GetFullPath(Path.Combine(targetDir, mod)); @@ -42,8 +43,19 @@ public async Task ProcessMod(string baseDir, string targetDir, s var res = EUpgradeResult.Failure; try { - var s = await ModpackUpgrader.UpgradeModpack(source, target); - res = s ? EUpgradeResult.Success : EUpgradeResult.Unchanged; + var result = await ModpackUpgrader.UpgradeModpack(source, target, false); + + if (!result) + { + // If we did nothing, just direct copy the mod, rather than doing the more expensive + // PMP write. + IOUtil.CopyFolder(source, target); + } + + res = result ? EUpgradeResult.Success : EUpgradeResult.Unchanged; + + + } catch (Exception ex) { if (Directory.Exists(target)) @@ -74,13 +86,26 @@ public async Task ProcessMod(string baseDir, string targetDir, s Trace.WriteLine(ex); } - await IOUtil.CompressWindowsDirectory(target); + if (compress) + { + await IOUtil.CompressWindowsDirectory(target); + } - if (Upgrades.ContainsKey(mod)) + lock (PenumbraLibraryUpgradeWindow._ResultsLock) { - Upgrades[mod] = res; + if (Upgrades.ContainsKey(mod)) + { + Upgrades[mod] = res; + } } return res; } + + public object Clone() + { + var cl = (PenumbraUpgradeStatus) MemberwiseClone(); + cl.Upgrades = new Dictionary(Upgrades); + return cl; + } } } diff --git a/FFXIV_TexTools/Resources/UIStrings.Designer.cs b/FFXIV_TexTools/Resources/UIStrings.Designer.cs index 4de0624c..a820d4f2 100644 --- a/FFXIV_TexTools/Resources/UIStrings.Designer.cs +++ b/FFXIV_TexTools/Resources/UIStrings.Designer.cs @@ -1963,7 +1963,7 @@ public static string Import_Raw { } /// - /// Looks up a localized string similar to Import Raw File. + /// Looks up a localized string similar to Import File. /// public static string Import_Raw_File { get { @@ -3616,7 +3616,7 @@ public static string Racial_Settings_Editor { } /// - /// Looks up a localized string similar to Raw File Operations. + /// Looks up a localized string similar to File Operations. /// public static string Raw_File_Operations { get { diff --git a/FFXIV_TexTools/Resources/UIStrings.resx b/FFXIV_TexTools/Resources/UIStrings.resx index ae1aa370..7ca15c7b 100644 --- a/FFXIV_TexTools/Resources/UIStrings.resx +++ b/FFXIV_TexTools/Resources/UIStrings.resx @@ -1004,7 +1004,7 @@ If you would like to enable this, first import a texture for the selected item.< Import Raw File - Raw File Operations + File Operations Clean Up Modlist @@ -1163,7 +1163,7 @@ If you would like to enable this, first import a texture for the selected item.< Extract File - Import Raw File + Import File Destination Path: diff --git a/FFXIV_TexTools/Resources/XivStrings.Designer.cs b/FFXIV_TexTools/Resources/XivStrings.Designer.cs index c79df8be..c946a778 100644 --- a/FFXIV_TexTools/Resources/XivStrings.Designer.cs +++ b/FFXIV_TexTools/Resources/XivStrings.Designer.cs @@ -19,7 +19,7 @@ namespace FFXIV_TexTools.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class XivStrings { @@ -60,6 +60,15 @@ internal XivStrings() { } } + /// + /// Looks up a localized string similar to Accessories. + /// + internal static string Accessories { + get { + return ResourceManager.GetString("Accessories", resourceCulture); + } + } + /// /// Looks up a localized string similar to Accessory. /// @@ -123,6 +132,15 @@ internal static string AutodeskCollada { } } + /// + /// Looks up a localized string similar to Beneficial. + /// + internal static string Beneficial { + get { + return ResourceManager.GetString("Beneficial", resourceCulture); + } + } + /// /// Looks up a localized string similar to Bishop Autoturret. /// @@ -222,6 +240,15 @@ internal static string DemiHuman { } } + /// + /// Looks up a localized string similar to Detrimental. + /// + internal static string Detrimental { + get { + return ResourceManager.GetString("Detrimental", resourceCulture); + } + } + /// /// Looks up a localized string similar to Diffuse. /// @@ -852,6 +879,15 @@ internal static string Ornaments { } } + /// + /// Looks up a localized string similar to Other. + /// + internal static string Other { + get { + return ResourceManager.GetString("Other", resourceCulture); + } + } + /// /// Looks up a localized string similar to Outdoor Furniture. /// @@ -1149,6 +1185,15 @@ internal static string Weapon { } } + /// + /// Looks up a localized string similar to Weapons. + /// + internal static string Weapons { + get { + return ResourceManager.GetString("Weapons", resourceCulture); + } + } + /// /// Looks up a localized string similar to Weather. /// @@ -1166,26 +1211,5 @@ internal static string Wrists { return ResourceManager.GetString("Wrists", resourceCulture); } } - internal static string Beneficial - { - get - { - return ResourceManager.GetString("Beneficial", resourceCulture); - } - } - internal static string Detrimental - { - get - { - return ResourceManager.GetString("Detrimental", resourceCulture); - } - } - internal static string Other - { - get - { - return ResourceManager.GetString("Other", resourceCulture); - } - } } } diff --git a/FFXIV_TexTools/Resources/XivStrings.resx b/FFXIV_TexTools/Resources/XivStrings.resx index 254d6343..4ffc28f2 100644 --- a/FFXIV_TexTools/Resources/XivStrings.resx +++ b/FFXIV_TexTools/Resources/XivStrings.resx @@ -495,4 +495,10 @@ Other + + Accessories + + + Weapons + \ No newline at end of file diff --git a/FFXIV_TexTools/ViewModels/FullModelViewModel.cs b/FFXIV_TexTools/ViewModels/FullModelViewModel.cs index 3025f5ba..15a3ae27 100644 --- a/FFXIV_TexTools/ViewModels/FullModelViewModel.cs +++ b/FFXIV_TexTools/ViewModels/FullModelViewModel.cs @@ -803,12 +803,13 @@ private async Task UpdateBodyTextures(TTModel ttModel, IItemModel item, Dictiona .FirstOrDefault(); bTex.MaterialPath = newMaterial; + var tx = MainWindow.DefaultTransaction; var mtrlPath = Mtrl.GetMtrlPath(tempMdlPath, newMaterial, mtrlVariant); - var mtrl = await Mtrl.GetXivMtrl(mtrlPath); + var mtrl = await Mtrl.GetXivMtrl(mtrlPath, false, tx); var colors = ModelTexture.GetCustomColors(); colors.InvertNormalGreen = false; - var modelMaps = await ModelTexture.GetModelMaps(mtrl, false, colors, -1, MainWindow.UserTransaction); + var modelMaps = await ModelTexture.GetModelMaps(mtrl, false, colors, -1, tx); // Reindex the material dictionary as materials may have sorted differently ReIndexMaterialDictionary(ttModel, materialDictionary, modelMaps); diff --git a/FFXIV_TexTools/Views/Controls/ItemSelectControl.xaml.cs b/FFXIV_TexTools/Views/Controls/ItemSelectControl.xaml.cs index cd42c442..d1347358 100644 --- a/FFXIV_TexTools/Views/Controls/ItemSelectControl.xaml.cs +++ b/FFXIV_TexTools/Views/Controls/ItemSelectControl.xaml.cs @@ -278,6 +278,50 @@ private void BuildSetTree() private void PreloadBaseCategories() { + var weapons = new ItemTreeElement(null, null, XivStrings.Weapons); + CategoryElements.Add(weapons); + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Shield.GetNiceName())); + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Sword.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Axe.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Broadsword.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Gunblade.GetNiceName())); + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Staff.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Orrery.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Nouliths.GetNiceName())); + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Fists.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Lance.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Daggers.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Katana.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Scythe.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Twinfangs.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Bow.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Gun.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Glaives.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Wand.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Book.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Rapier.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Brush.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Cane.GetNiceName())); + + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Saw.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.CrossPeinHammer.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.RaisingHammer.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.LapidaryHammer.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Needle.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.RoundKnife.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Alembic.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.CulinaryKnife.GetNiceName())); + + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Pickaxe.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.Hatchet.GetNiceName())); + weapons.Children.Add(new ItemTreeElement(null, null, XivWeaponType.FishingRod.GetNiceName())); + + var gear = new ItemTreeElement(null, null, XivStrings.Gear); CategoryElements.Add(gear); @@ -287,17 +331,6 @@ private void PreloadBaseCategories() gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Legs)); gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Feet)); - - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Main_Hand)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Off_Hand)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Dual_Wield)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Two_Handed)); - - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Earring)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Neck)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Wrists)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Rings)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Head_Body)); gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Body_Hands)); gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Body_Hands_Legs)); @@ -305,7 +338,15 @@ private void PreloadBaseCategories() gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Legs_Feet)); gear.Children.Add(new ItemTreeElement(null, null, XivStrings.All)); - gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Food)); + //gear.Children.Add(new ItemTreeElement(null, null, XivStrings.Food)); + + + var accessories = new ItemTreeElement(null, null, XivStrings.Accessories); + CategoryElements.Add(accessories); + accessories.Children.Add(new ItemTreeElement(null, null, XivStrings.Earring)); + accessories.Children.Add(new ItemTreeElement(null, null, XivStrings.Neck)); + accessories.Children.Add(new ItemTreeElement(null, null, XivStrings.Wrists)); + accessories.Children.Add(new ItemTreeElement(null, null, XivStrings.Rings)); } private async Task> BuildCategoryTree() diff --git a/FFXIV_TexTools/Views/Upgrades/PenumbraLibraryUpgradeWindow.xaml b/FFXIV_TexTools/Views/Upgrades/PenumbraLibraryUpgradeWindow.xaml index c56daae3..2945b1ce 100644 --- a/FFXIV_TexTools/Views/Upgrades/PenumbraLibraryUpgradeWindow.xaml +++ b/FFXIV_TexTools/Views/Upgrades/PenumbraLibraryUpgradeWindow.xaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:FFXIV_TexTools.Views.Upgrades" mc:Ignorable="d" - Title="Penumbra Library Update Tool" Height="450" Width="800"> + Title="Penumbra Library Update Tool" Height="600" Width="800"> @@ -32,12 +32,25 @@ +