From afa804394f2a8a3ac632a7c287ce1f19a76dfbaf Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sat, 7 Feb 2026 23:00:20 +0100 Subject: [PATCH] Some minor fixes, changelog updates, do not include SHPKs in swaps by default. --- Penumbra/Config/Configuration.cs | 4 ++ Penumbra/Mods/ItemSwap/EquipmentSwap.cs | 7 +++- Penumbra/Services/MigrationManager.cs | 3 -- Penumbra/UI/AdvancedWindow/ItemSwapTab.cs | 32 +++++++++++----- .../UI/AdvancedWindow/ResourceTreeViewer.cs | 38 +++++++++---------- Penumbra/UI/Changelog.cs | 5 ++- Penumbra/UI/Classes/CollectionSelectHeader.cs | 5 ++- Penumbra/UI/Combos/SingleGroupCombo.cs | 7 +++- Penumbra/UI/ModsTab/Groups/ModGroupDrawer.cs | 2 +- .../UI/ModsTab/Groups/ModGroupEditDrawer.cs | 6 +-- Penumbra/UI/ModsTab/ModPanelEditTab.cs | 12 ++++-- Penumbra/UI/ModsTab/RedrawFooter.cs | 2 +- 12 files changed, 77 insertions(+), 46 deletions(-) diff --git a/Penumbra/Config/Configuration.cs b/Penumbra/Config/Configuration.cs index 587d5dfa..978b1153 100644 --- a/Penumbra/Config/Configuration.cs +++ b/Penumbra/Config/Configuration.cs @@ -73,6 +73,10 @@ public partial class Configuration : IPluginConfiguration, ISavable, IService public bool EnableAutomaticModImport { get; set; } = false; public bool PreventExportLoopback { get; set; } = true; public bool EnableCustomShapes { get; set; } = true; + + [ConfigProperty] + private bool _includeShpkInSwap = false; + public PcpSettings PcpSettings = new(); [ConfigProperty] diff --git a/Penumbra/Mods/ItemSwap/EquipmentSwap.cs b/Penumbra/Mods/ItemSwap/EquipmentSwap.cs index 216b5841..8e309fc4 100644 --- a/Penumbra/Mods/ItemSwap/EquipmentSwap.cs +++ b/Penumbra/Mods/ItemSwap/EquipmentSwap.cs @@ -460,8 +460,11 @@ public static class EquipmentSwap } var mtrl = FileSwap.CreateSwap(manager, ResourceType.Mtrl, redirections, pathFrom, pathTo); - var shpk = CreateShader(manager, redirections, ref mtrl.AsMtrl()!.ShaderPackage.Name, ref mtrl.DataWasChanged); - mtrl.ChildSwaps.Add(shpk); + if (manager.Config.IncludeShpkInSwap) + { + var shpk = CreateShader(manager, redirections, ref mtrl.AsMtrl()!.ShaderPackage.Name, ref mtrl.DataWasChanged); + mtrl.ChildSwaps.Add(shpk); + } foreach (ref var texture in mtrl.AsMtrl()!.Textures.AsSpan()) { diff --git a/Penumbra/Services/MigrationManager.cs b/Penumbra/Services/MigrationManager.cs index 1de0981f..34cf864f 100644 --- a/Penumbra/Services/MigrationManager.cs +++ b/Penumbra/Services/MigrationManager.cs @@ -2,11 +2,8 @@ using Dalamud.Interface.ImGuiNotification; using Lumina.Data.Files; using Lumina.Extensions; using Luna; -using Penumbra.GameData.Files.Utility; using Penumbra.Import.Textures; using Penumbra.Util; -using SharpCompress.Common; -using SharpCompress.Readers; using MdlFile = Penumbra.GameData.Files.MdlFile; using MtrlFile = Penumbra.GameData.Files.MtrlFile; diff --git a/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs b/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs index ea1f9dba..6b458001 100644 --- a/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs +++ b/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs @@ -34,6 +34,7 @@ public enum SwapType Necklace, Bracelet, Ring, + [Name("Between Slots")] BetweenSlots, Hair, @@ -44,7 +45,6 @@ public enum SwapType Glasses, } - [NamedEnum(Utf16: false)] public enum BetweenSlotTypes { @@ -52,8 +52,10 @@ public enum BetweenSlotTypes Earrings, Necklace, Bracelets, + [Name("Right Ring")] RightRing, + [Name("Left Ring")] LeftRing, Glasses, @@ -403,8 +405,7 @@ public class ItemSwapTab : IDisposable, ITab if (ImEx.Button("Create New Mod"u8, new Vector2(width / 2, 0), tt, !newModAvailable || _newModName.Length is 0)) CreateMod(); - Im.Line.Same(); - Im.Cursor.X += 20 * Im.Style.GlobalScale; + Im.Line.Same(0, 20 * Im.Style.GlobalScale + Im.Style.ItemSpacing.X); Im.Checkbox("Use File Swaps"u8, ref _useFileSwaps); Im.Tooltip.OnHover("Instead of writing every single non-default file to the newly created mod or option,\n"u8 + "even those available from game files, use File Swaps to default game files where possible."u8); @@ -427,11 +428,21 @@ public class ItemSwapTab : IDisposable, ITab if (ImEx.Button("Create New Option"u8, new Vector2(width / 2, 0), tt, !newModAvailable || !_subModValid)) CreateOption(); - Im.Line.Same(); - Im.Cursor.X += 20 * Im.Style.GlobalScale; + Im.Line.Same(0, 20 * Im.Style.GlobalScale + Im.Style.ItemSpacing.X); _dirty |= Im.Checkbox("Use Entire Collection"u8, ref _useCurrentCollection); - Im.Tooltip.OnHover("Use all applied mods from the Selected Collection with their current settings and respecting the enabled state of mods and inheritance,\n"u8 + Im.Tooltip.OnHover( + "Use all applied mods from the Selected Collection with their current settings and respecting the enabled state of mods and inheritance,\n"u8 + "instead of using only the selected mod with its current settings in the Selected collection or the default settings, ignoring the enabled state and inheritance."u8); + + Im.Line.Same(0, 20 * Im.Style.GlobalScale); + if (Im.Checkbox("Include Shader Packs"u8, _config.IncludeShpkInSwap)) + { + _config.IncludeShpkInSwap ^= true; + _dirty = true; + } + + Im.Tooltip.OnHover( + "Generally you do not want to include shader packs (*.shpk) files in your item swap since they are a much more global object than a single item.\n\nOnly enable this if you are really sure about what you are doing."u8); } private void DrawSwapBar() @@ -544,7 +555,7 @@ public class ItemSwapTab : IDisposable, ITab BetweenSlotTypes.Necklace => RefTuple.Create(SwapType.Necklace, "this"u8, "it"u8), BetweenSlotTypes.Bracelets => RefTuple.Create(SwapType.Bracelet, "these"u8, "them"u8), BetweenSlotTypes.RightRing => RefTuple.Create(SwapType.Ring, "this"u8, "it"u8), - BetweenSlotTypes.LeftRing => RefTuple.Create(SwapType.Ring, "this"u8, "it"u8), + BetweenSlotTypes.LeftRing => RefTuple.Create(SwapType.Ring, "this"u8, "it"u8), BetweenSlotTypes.Glasses => RefTuple.Create(SwapType.Glasses, "these"u8, "them"u8), _ => RefTuple.Create(SwapType.Ring, "this"u8, "it"u8), }; @@ -562,9 +573,11 @@ public class ItemSwapTab : IDisposable, ITab using var table = Im.Table.Begin("##settings"u8, 2, TableFlags.SizingFixedFit); if (!table) return; + table.DrawFrameColumn(text1); table.NextColumn(); - _dirty |= sourceSelector.Draw("##itemSource"u8, sourceSelector.CurrentSelection.Name, StringU8.Empty, InputWidth * 2 * Im.Style.GlobalScale, out _); + _dirty |= sourceSelector.Draw("##itemSource"u8, sourceSelector.CurrentSelection.Name, StringU8.Empty, + InputWidth * 2 * Im.Style.GlobalScale, out _); if (type is SwapType.Ring) { @@ -574,7 +587,8 @@ public class ItemSwapTab : IDisposable, ITab table.DrawFrameColumn(text2); table.NextColumn(); - _dirty |= targetSelector.Draw("##itemTarget"u8, targetSelector.CurrentSelection.Name, StringU8.Empty, InputWidth * 2 * Im.Style.GlobalScale, out _); + _dirty |= targetSelector.Draw("##itemTarget"u8, targetSelector.CurrentSelection.Name, StringU8.Empty, + InputWidth * 2 * Im.Style.GlobalScale, out _); if (type is SwapType.Ring) { Im.Line.Same(); diff --git a/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs b/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs index 59b11eb3..62caf27f 100644 --- a/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs +++ b/Penumbra/UI/AdvancedWindow/ResourceTreeViewer.cs @@ -203,25 +203,25 @@ public class ResourceTreeViewer( } } - using (ImStyleSingle.FrameRounding.Push(0)) - { - var fieldWidth = (Im.ContentRegion.Available.X - checkSpacing * 2.0f - Im.Style.FrameHeightWithSpacing) / 2.0f; - Im.Item.SetNextWidth(fieldWidth); - var filter = config.Filters.OnScreenCharacterFilter; - if (Im.Input.Text("##TreeNameFilter"u8, ref filter, "Filter by Character/Entity Name..."u8)) - { - filterChanged = true; - config.Filters.OnScreenCharacterFilter = filter; - } - - Im.Line.Same(0, checkSpacing); - Im.Item.SetNextWidth(fieldWidth); - filter = config.Filters.OnScreenItemFilter; - if (Im.Input.Text("##NodeFilter"u8, ref filter, "Filter by Item/Part Name or Path..."u8)) - { - filterChanged = true; - config.Filters.OnScreenItemFilter = filter; - } + using (ImStyleSingle.FrameRounding.Push(0)) + { + var fieldWidth = (Im.ContentRegion.Available.X - checkSpacing * 2.0f - Im.Style.FrameHeightWithSpacing) / 2.0f; + Im.Item.SetNextWidth(fieldWidth); + var filter = config.Filters.OnScreenCharacterFilter; + if (Im.Input.Text("##TreeNameFilter"u8, ref filter, "Filter by Character/Entity Name..."u8)) + { + filterChanged = true; + config.Filters.OnScreenCharacterFilter = filter; + } + + Im.Line.Same(0, checkSpacing); + Im.Item.SetNextWidth(fieldWidth); + filter = config.Filters.OnScreenItemFilter; + if (Im.Input.Text("##NodeFilter"u8, ref filter, "Filter by Item/Part Name or Path..."u8)) + { + filterChanged = true; + config.Filters.OnScreenItemFilter = filter; + } } Im.Line.Same(0, checkSpacing); diff --git a/Penumbra/UI/Changelog.cs b/Penumbra/UI/Changelog.cs index 8490720b..a558dfa6 100644 --- a/Penumbra/UI/Changelog.cs +++ b/Penumbra/UI/Changelog.cs @@ -79,7 +79,10 @@ public class PenumbraChangelog : IUiService .RegisterEntry( "Dragging mods into the game to install them should no longer need to drop them into the mod selector, or having the Penumbra window open. Dragging into the game window should be enough."u8, 1) + .RegisterEntry("The mod import popup has been relegated to a Dalamud notification. The popup itself only opens when further details are requested on the notification (Thanks Ny!)."u8) + .RegisterEntry("The notification should also gather multiple import activities without creating multiple popups."u8, 1) .RegisterEntry("Many UI widgets should be more precise and consistent."u8, 1) + .RegisterHighlight("Made it possible to have multiple Advanced Editing windows open at once (Thanks Ny!)."u8) .RegisterHighlight("A new 'Management' tab was added."u8) .RegisterEntry("The management tab is supposed to help users get rid of unused mods."u8, 1) .RegisterEntry( @@ -89,13 +92,13 @@ public class PenumbraChangelog : IUiService "New IPC was added so that other plugins can register to add notes when inactive mods are queried or mark them as active."u8, 1) .RegisterEntry("The Duplicate Mods panel checks for multiple mods with the same name."u8, 1) .RegisterEntry("Cleanup functions have been moved from Advanced Settings to the General Cleanup panel."u8, 1) + .RegisterEntry("The attachment points BLD and BL2 have been identified as Twinblades."u8) .RegisterHighlight("Add support for other block compression types in the texture compression IPC (1.5.1.12)."u8) .RegisterHighlight( "Added IPC to provide Penumbra-related settings of other plugins in the Penumbra Settings tab (Thanks Ny!) (1.5.1.9)."u8) .RegisterEntry("Fixed multiple issues in the advanced editing tab for materials (Thanks Ny!) (1.5.1.9)."u8) .RegisterEntry("Added IPC to redraw members of a specific collection (Thanks Karou!) (1.5.1.8)."u8) .RegisterEntry("Fixed an issue when other plugins set a cutscene index through API (1.5.1.7)."u8) - .RegisterHighlight("Made it possible to have multiple Advanced Editing windows open at once (Thanks Ny!) (1.5.1.7)."u8) .RegisterHighlight( "Added a file watcher that automatically tries to install mods when saved into a configured directory (Thanks Stoia!) (1.5.1.7)."u8) .RegisterEntry( diff --git a/Penumbra/UI/Classes/CollectionSelectHeader.cs b/Penumbra/UI/Classes/CollectionSelectHeader.cs index 6e41cf33..d4bee45a 100644 --- a/Penumbra/UI/Classes/CollectionSelectHeader.cs +++ b/Penumbra/UI/Classes/CollectionSelectHeader.cs @@ -70,7 +70,7 @@ public class CollectionSelectHeader( } Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, - "Toggle the temporary settings mode, where all changes you do create temporary settings first and need to be made permanent if desired."u8); + "Toggle the temporary settings mode, where all changes you do create temporary settings first and need to be made permanent if desired."u8, true); if (!hold) Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"\nHold {config.IncognitoModifier} while clicking to toggle."); } @@ -158,8 +158,9 @@ public class CollectionSelectHeader( { var (collection, name, tooltip, disabled) = tuple; using var _ = Im.Id.Push(id); - if (ImEx.Button(name, buttonWidth, tooltip, disabled)) + if (ImEx.Button(name, buttonWidth, StringU8.Empty, disabled)) _activeCollections.SetCollection(collection!, CollectionType.Current); + Im.Tooltip.OnHover(ref tooltip, HoveredFlags.AllowWhenDisabled, true); Im.Line.Same(); } diff --git a/Penumbra/UI/Combos/SingleGroupCombo.cs b/Penumbra/UI/Combos/SingleGroupCombo.cs index f340ee11..ab7b12a0 100644 --- a/Penumbra/UI/Combos/SingleGroupCombo.cs +++ b/Penumbra/UI/Combos/SingleGroupCombo.cs @@ -24,9 +24,10 @@ public sealed class SingleGroupCombo : FilterComboBase, I public void Draw(ModGroupDrawer parent, SingleModGroup group, int groupIndex, Setting currentOption) { + using var id = Im.Id.Push(groupIndex); _currentOption = currentOption; _group.SetTarget(group); - if (base.Draw(group.Name, group.OptionData[currentOption.AsIndex].Name, StringU8.Empty, UiHelpers.InputTextWidth.X * 3 / 4, + if (base.Draw(StringU8.Empty, group.OptionData[currentOption.AsIndex].Name, StringU8.Empty, UiHelpers.InputTextWidth.X * 3 / 4, out var newOption)) parent.SetModSetting(group, groupIndex, Setting.Single(newOption.OptionIndex)); } @@ -43,7 +44,11 @@ public sealed class SingleGroupCombo : FilterComboBase, I { var ret = Im.Selectable(item.Name, selected); if (item.Description.Length > 0) + { + Im.Line.SameInner(); LunaStyle.DrawHelpMarker(item.Description, treatAsHovered: Im.Item.Hovered()); + } + return ret; } diff --git a/Penumbra/UI/ModsTab/Groups/ModGroupDrawer.cs b/Penumbra/UI/ModsTab/Groups/ModGroupDrawer.cs index 3ab02759..6cc92ed0 100644 --- a/Penumbra/UI/ModsTab/Groups/ModGroupDrawer.cs +++ b/Penumbra/UI/ModsTab/Groups/ModGroupDrawer.cs @@ -26,7 +26,7 @@ public sealed class ModGroupDrawer(Configuration config, CollectionManager colle _blockGroupCache.Clear(); _settings = settings; _tempSettings = tempSettings; - _temporary = tempSettings != null; + _temporary = tempSettings is not null; _locked = (tempSettings?.Lock ?? 0) > 0; var useDummy = true; foreach (var (idx, group) in mod.Groups.Index()) diff --git a/Penumbra/UI/ModsTab/Groups/ModGroupEditDrawer.cs b/Penumbra/UI/ModsTab/Groups/ModGroupEditDrawer.cs index 0a4819db..282da2d1 100644 --- a/Penumbra/UI/ModsTab/Groups/ModGroupEditDrawer.cs +++ b/Penumbra/UI/ModsTab/Groups/ModGroupEditDrawer.cs @@ -44,9 +44,9 @@ public sealed class ModGroupEditDrawer( private float _spacing; private bool _deleteEnabled; - private string? _currentGroupName; - private IModGroup? _currentGroupEdited; - private bool _isGroupNameValid = true; + private string? _currentGroupName; + private IModGroup? _currentGroupEdited; + private bool _isGroupNameValid = true; private IModGroup? _dragDropGroup; private IModOption? _dragDropOption; diff --git a/Penumbra/UI/ModsTab/ModPanelEditTab.cs b/Penumbra/UI/ModsTab/ModPanelEditTab.cs index 4c307f0b..778beded 100644 --- a/Penumbra/UI/ModsTab/ModPanelEditTab.cs +++ b/Penumbra/UI/ModsTab/ModPanelEditTab.cs @@ -72,12 +72,16 @@ public class ModPanelEditTab( if (sharedTagsEnabled) predefinedTagManager.DrawAddFromSharedTagsAndUpdateTags(_mod.LocalTags, _mod.ModTags, false, _mod); - - UiHelpers.DefaultLineSpace(); - addGroupDrawer.Draw(_mod, UiHelpers.InputTextWidth.X); UiHelpers.DefaultLineSpace(); + if (Im.Tree.Header("Group Editing"u8)) + { + UiHelpers.DefaultLineSpace(); + addGroupDrawer.Draw(_mod, UiHelpers.InputTextWidth.X); + UiHelpers.DefaultLineSpace(); + + groupEditDrawer.Draw(_mod); + } - groupEditDrawer.Draw(_mod); descriptionPopup.Draw(); } diff --git a/Penumbra/UI/ModsTab/RedrawFooter.cs b/Penumbra/UI/ModsTab/RedrawFooter.cs index db5a098b..bc9e4049 100644 --- a/Penumbra/UI/ModsTab/RedrawFooter.cs +++ b/Penumbra/UI/ModsTab/RedrawFooter.cs @@ -55,7 +55,7 @@ public sealed class RedrawFooter( public void Draw(Vector2 size) { - using var style = Im.Style.PushDefault(ImStyleDouble.FramePadding); + using var style = Im.Style.PushDefault(ImStyleDouble.WindowPadding); DrawInfo(size with { X = 0 }); DrawTooltip();