Make items changed in a mod sort before other items for item swap, also color them.

This commit is contained in:
Ottermandias 2024-07-26 18:42:48 +02:00
parent 72f2834dfd
commit 246f4f65f5
3 changed files with 44 additions and 33 deletions

View file

@ -22,6 +22,7 @@ using Penumbra.Mods.Settings;
using Penumbra.Mods.SubMods;
using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.UI.ModsTab;
namespace Penumbra.UI.AdvancedWindow;
@ -34,7 +35,8 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
private readonly MetaFileManager _metaFileManager;
public ItemSwapTab(CommunicatorService communicator, ItemData itemService, CollectionManager collectionManager,
ModManager modManager, ObjectIdentification identifier, MetaFileManager metaFileManager, Configuration config)
ModManager modManager, ModFileSystemSelector selector, ObjectIdentification identifier, MetaFileManager metaFileManager,
Configuration config)
{
_communicator = communicator;
_collectionManager = collectionManager;
@ -46,15 +48,15 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
_selectors = new Dictionary<SwapType, (ItemSelector Source, ItemSelector Target, string TextFrom, string TextTo)>
{
// @formatter:off
[SwapType.Hat] = (new ItemSelector(itemService, FullEquipType.Head), new ItemSelector(itemService, FullEquipType.Head), "Take this Hat", "and put it on this one" ),
[SwapType.Top] = (new ItemSelector(itemService, FullEquipType.Body), new ItemSelector(itemService, FullEquipType.Body), "Take this Top", "and put it on this one" ),
[SwapType.Gloves] = (new ItemSelector(itemService, FullEquipType.Hands), new ItemSelector(itemService, FullEquipType.Hands), "Take these Gloves", "and put them on these" ),
[SwapType.Pants] = (new ItemSelector(itemService, FullEquipType.Legs), new ItemSelector(itemService, FullEquipType.Legs), "Take these Pants", "and put them on these" ),
[SwapType.Shoes] = (new ItemSelector(itemService, FullEquipType.Feet), new ItemSelector(itemService, FullEquipType.Feet), "Take these Shoes", "and put them on these" ),
[SwapType.Earrings] = (new ItemSelector(itemService, FullEquipType.Ears), new ItemSelector(itemService, FullEquipType.Ears), "Take these Earrings", "and put them on these" ),
[SwapType.Necklace] = (new ItemSelector(itemService, FullEquipType.Neck), new ItemSelector(itemService, FullEquipType.Neck), "Take this Necklace", "and put it on this one" ),
[SwapType.Bracelet] = (new ItemSelector(itemService, FullEquipType.Wrists), new ItemSelector(itemService, FullEquipType.Wrists), "Take these Bracelets", "and put them on these" ),
[SwapType.Ring] = (new ItemSelector(itemService, FullEquipType.Finger), new ItemSelector(itemService, FullEquipType.Finger), "Take this Ring", "and put it on this one" ),
[SwapType.Hat] = (new ItemSelector(itemService, selector, FullEquipType.Head), new ItemSelector(itemService, null, FullEquipType.Head), "Take this Hat", "and put it on this one" ),
[SwapType.Top] = (new ItemSelector(itemService, selector, FullEquipType.Body), new ItemSelector(itemService, null, FullEquipType.Body), "Take this Top", "and put it on this one" ),
[SwapType.Gloves] = (new ItemSelector(itemService, selector, FullEquipType.Hands), new ItemSelector(itemService, null, FullEquipType.Hands), "Take these Gloves", "and put them on these" ),
[SwapType.Pants] = (new ItemSelector(itemService, selector, FullEquipType.Legs), new ItemSelector(itemService, null, FullEquipType.Legs), "Take these Pants", "and put them on these" ),
[SwapType.Shoes] = (new ItemSelector(itemService, selector, FullEquipType.Feet), new ItemSelector(itemService, null, FullEquipType.Feet), "Take these Shoes", "and put them on these" ),
[SwapType.Earrings] = (new ItemSelector(itemService, selector, FullEquipType.Ears), new ItemSelector(itemService, null, FullEquipType.Ears), "Take these Earrings", "and put them on these" ),
[SwapType.Necklace] = (new ItemSelector(itemService, selector, FullEquipType.Neck), new ItemSelector(itemService, null, FullEquipType.Neck), "Take this Necklace", "and put it on this one" ),
[SwapType.Bracelet] = (new ItemSelector(itemService, selector, FullEquipType.Wrists), new ItemSelector(itemService, null, FullEquipType.Wrists), "Take these Bracelets", "and put them on these" ),
[SwapType.Ring] = (new ItemSelector(itemService, selector, FullEquipType.Finger), new ItemSelector(itemService, null, FullEquipType.Finger), "Take this Ring", "and put it on this one" ),
// @formatter:on
};
@ -129,11 +131,24 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
Weapon,
}
private class ItemSelector(ItemData data, FullEquipType type)
: FilterComboCache<EquipItem>(() => data.ByType[type], MouseWheelType.None, Penumbra.Log)
private class ItemSelector(ItemData data, ModFileSystemSelector? selector, FullEquipType type)
: FilterComboCache<(EquipItem Item, bool InMod)>(() =>
{
var list = data.ByType[type];
if (selector?.Selected is { } mod && mod.ChangedItems.Values.Any(o => o is EquipItem i && i.Type == type))
return list.Select(i => (i, mod.ChangedItems.ContainsKey(i.Name))).OrderByDescending(p => p.Item2).ToList();
return list.Select(i => (i, false)).ToList();
}, MouseWheelType.None, Penumbra.Log)
{
protected override string ToString(EquipItem obj)
=> obj.Name;
protected override bool DrawSelectable(int globalIdx, bool selected)
{
using var color = ImRaii.PushColor(ImGuiCol.Text, ColorId.ResTreeLocalPlayer.Value(), Items[globalIdx].InMod);
return base.DrawSelectable(globalIdx, selected);
}
protected override string ToString((EquipItem Item, bool InMod) obj)
=> obj.Item.Name;
}
private readonly Dictionary<SwapType, (ItemSelector Source, ItemSelector Target, string TextFrom, string TextTo)> _selectors;
@ -186,17 +201,17 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
case SwapType.Bracelet:
case SwapType.Ring:
var values = _selectors[_lastTab];
if (values.Source.CurrentSelection.Type != FullEquipType.Unknown
&& values.Target.CurrentSelection.Type != FullEquipType.Unknown)
_affectedItems = _swapData.LoadEquipment(values.Target.CurrentSelection, values.Source.CurrentSelection,
if (values.Source.CurrentSelection.Item.Type != FullEquipType.Unknown
&& values.Target.CurrentSelection.Item.Type != FullEquipType.Unknown)
_affectedItems = _swapData.LoadEquipment(values.Target.CurrentSelection.Item, values.Source.CurrentSelection.Item,
_useCurrentCollection ? _collectionManager.Active.Current : null, _useRightRing, _useLeftRing);
break;
case SwapType.BetweenSlots:
var (_, _, selectorFrom) = GetAccessorySelector(_slotFrom, true);
var (_, _, selectorTo) = GetAccessorySelector(_slotTo, false);
if (selectorFrom.CurrentSelection.Valid && selectorTo.CurrentSelection.Valid)
_affectedItems = _swapData.LoadTypeSwap(_slotTo, selectorTo.CurrentSelection, _slotFrom, selectorFrom.CurrentSelection,
if (selectorFrom.CurrentSelection.Item.Valid && selectorTo.CurrentSelection.Item.Valid)
_affectedItems = _swapData.LoadTypeSwap(_slotTo, selectorTo.CurrentSelection.Item, _slotFrom, selectorFrom.CurrentSelection.Item,
_useCurrentCollection ? _collectionManager.Active.Current : null);
break;
case SwapType.Hair when _targetId > 0 && _sourceId > 0:
@ -455,7 +470,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
}
ImGui.TableNextColumn();
_dirty |= selector.Draw("##itemSource", selector.CurrentSelection.Name ?? string.Empty, string.Empty, InputWidth * 2 * UiHelpers.Scale,
_dirty |= selector.Draw("##itemSource", selector.CurrentSelection.Item.Name ?? string.Empty, string.Empty, InputWidth * 2 * UiHelpers.Scale,
ImGui.GetTextLineHeightWithSpacing());
(article1, _, selector) = GetAccessorySelector(_slotTo, false);
@ -480,7 +495,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
ImGui.TableNextColumn();
_dirty |= selector.Draw("##itemTarget", selector.CurrentSelection.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
_dirty |= selector.Draw("##itemTarget", selector.CurrentSelection.Item.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
ImGui.GetTextLineHeightWithSpacing());
if (_affectedItems is not { Length: > 1 })
return;
@ -489,7 +504,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
ImGuiUtil.DrawTextButton($"which will also affect {_affectedItems.Length - 1} other Items.", Vector2.Zero,
Colors.PressEnterWarningBg);
if (ImGui.IsItemHovered())
ImGui.SetTooltip(string.Join('\n', _affectedItems.Where(i => !ReferenceEquals(i.Name, selector.CurrentSelection.Name))
ImGui.SetTooltip(string.Join('\n', _affectedItems.Where(i => !ReferenceEquals(i.Name, selector.CurrentSelection.Item.Name))
.Select(i => i.Name)));
}
@ -521,7 +536,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(text1);
ImGui.TableNextColumn();
_dirty |= sourceSelector.Draw("##itemSource", sourceSelector.CurrentSelection.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
_dirty |= sourceSelector.Draw("##itemSource", sourceSelector.CurrentSelection.Item.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
ImGui.GetTextLineHeightWithSpacing());
if (type == SwapType.Ring)
@ -534,7 +549,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted(text2);
ImGui.TableNextColumn();
_dirty |= targetSelector.Draw("##itemTarget", targetSelector.CurrentSelection.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
_dirty |= targetSelector.Draw("##itemTarget", targetSelector.CurrentSelection.Item.Name, string.Empty, InputWidth * 2 * UiHelpers.Scale,
ImGui.GetTextLineHeightWithSpacing());
if (type == SwapType.Ring)
{
@ -549,7 +564,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
ImGuiUtil.DrawTextButton($"which will also affect {_affectedItems.Length - 1} other Items.", Vector2.Zero,
Colors.PressEnterWarningBg);
if (ImGui.IsItemHovered())
ImGui.SetTooltip(string.Join('\n', _affectedItems.Where(i => !ReferenceEquals(i.Name, targetSelector.CurrentSelection.Name))
ImGui.SetTooltip(string.Join('\n', _affectedItems.Where(i => !ReferenceEquals(i.Name, targetSelector.CurrentSelection.Item.Name))
.Select(i => i.Name)));
}