From 40b7266c22756d7d2916152b5fa9413b7371ee5d Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 8 Jan 2023 13:35:51 +0100 Subject: [PATCH] Add handling for left and right ring. --- Penumbra/Mods/ItemSwap/EquipmentSwap.cs | 129 +++++++++++--------- Penumbra/Mods/ItemSwap/ItemSwapContainer.cs | 4 +- Penumbra/UI/Classes/ItemSwapWindow.cs | 17 ++- 3 files changed, 91 insertions(+), 59 deletions(-) diff --git a/Penumbra/Mods/ItemSwap/EquipmentSwap.cs b/Penumbra/Mods/ItemSwap/EquipmentSwap.cs index 49e8ae66..4f49ef62 100644 --- a/Penumbra/Mods/ItemSwap/EquipmentSwap.cs +++ b/Penumbra/Mods/ItemSwap/EquipmentSwap.cs @@ -17,8 +17,24 @@ namespace Penumbra.Mods.ItemSwap; public static class EquipmentSwap { + private static EquipSlot[] ConvertSlots( EquipSlot slot, bool rFinger, bool lFinger ) + { + if( slot != EquipSlot.RFinger ) + { + return new[] { slot }; + } + + return rFinger + ? lFinger + ? new[] { EquipSlot.RFinger, EquipSlot.LFinger } + : new[] { EquipSlot.RFinger } + : lFinger + ? new[] { EquipSlot.LFinger } + : Array.Empty< EquipSlot >(); + } + public static Item[] CreateItemSwap( List< Swap > swaps, Func< Utf8GamePath, FullPath > redirections, Func< MetaManipulation, MetaManipulation > manips, Item itemFrom, - Item itemTo ) + Item itemTo, bool rFinger = true, bool lFinger = true ) { // Check actual ids, variants and slots. We only support using the same slot. LookupItem( itemFrom, out var slotFrom, out var idFrom, out var variantFrom ); @@ -40,69 +56,72 @@ public static class EquipmentSwap swaps.Add( gmp ); } - - var (imcFileFrom, variants, affectedItems) = GetVariants( slotFrom, idFrom, idTo, variantFrom ); - var imcFileTo = new ImcFile( new ImcManipulation( slotFrom, variantTo, idTo.Value, default ) ); - - var isAccessory = slotFrom.IsAccessory(); - var estType = slotFrom switch + var affectedItems = Array.Empty< Item >(); + foreach( var slot in ConvertSlots( slotFrom, rFinger, lFinger ) ) { - EquipSlot.Head => EstManipulation.EstType.Head, - EquipSlot.Body => EstManipulation.EstType.Body, - _ => ( EstManipulation.EstType )0, - }; + (var imcFileFrom, var variants, affectedItems) = GetVariants( slot, idFrom, idTo, variantFrom ); + var imcFileTo = new ImcFile( new ImcManipulation( slot, variantTo, idTo.Value, default ) ); - var skipFemale = false; - var skipMale = false; - var mtrlVariantTo = imcFileTo.GetEntry( ImcFile.PartIndex( slotFrom ), variantTo ).MaterialId; - foreach( var gr in Enum.GetValues< GenderRace >() ) - { - switch( gr.Split().Item1 ) + var isAccessory = slot.IsAccessory(); + var estType = slot switch { - case Gender.Male when skipMale: continue; - case Gender.Female when skipFemale: continue; - case Gender.MaleNpc when skipMale: continue; - case Gender.FemaleNpc when skipFemale: continue; - } + EquipSlot.Head => EstManipulation.EstType.Head, + EquipSlot.Body => EstManipulation.EstType.Body, + _ => ( EstManipulation.EstType )0, + }; - if( CharacterUtility.EqdpIdx( gr, isAccessory ) < 0 ) + var skipFemale = false; + var skipMale = false; + var mtrlVariantTo = imcFileTo.GetEntry( ImcFile.PartIndex( slot ), variantTo ).MaterialId; + foreach( var gr in Enum.GetValues< GenderRace >() ) { - continue; - } - - var est = ItemSwap.CreateEst( redirections, manips, estType, gr, idFrom, idTo ); - if( est != null ) - { - swaps.Add( est ); - } - - try - { - var eqdp = CreateEqdp( redirections, manips, slotFrom, gr, idFrom, idTo, mtrlVariantTo ); - if( eqdp != null ) + switch( gr.Split().Item1 ) { - swaps.Add( eqdp ); + case Gender.Male when skipMale: continue; + case Gender.Female when skipFemale: continue; + case Gender.MaleNpc when skipMale: continue; + case Gender.FemaleNpc when skipFemale: continue; + } + + if( CharacterUtility.EqdpIdx( gr, isAccessory ) < 0 ) + { + continue; + } + + var est = ItemSwap.CreateEst( redirections, manips, estType, gr, idFrom, idTo ); + if( est != null ) + { + swaps.Add( est ); + } + + try + { + var eqdp = CreateEqdp( redirections, manips, slot, gr, idFrom, idTo, mtrlVariantTo ); + if( eqdp != null ) + { + swaps.Add( eqdp ); + } + } + catch( ItemSwap.MissingFileException e ) + { + switch( gr ) + { + case GenderRace.MidlanderMale when e.Type == ResourceType.Mdl: + skipMale = true; + continue; + case GenderRace.MidlanderFemale when e.Type == ResourceType.Mdl: + skipFemale = true; + continue; + default: throw; + } } } - catch( ItemSwap.MissingFileException e ) - { - switch( gr ) - { - case GenderRace.MidlanderMale when e.Type == ResourceType.Mdl: - skipMale = true; - continue; - case GenderRace.MidlanderFemale when e.Type == ResourceType.Mdl: - skipFemale = true; - continue; - default: throw; - } - } - } - foreach( var variant in variants ) - { - var imc = CreateImc( redirections, manips, slotFrom, idFrom, idTo, variant, variantTo, imcFileFrom, imcFileTo ); - swaps.Add( imc ); + foreach( var variant in variants ) + { + var imc = CreateImc( redirections, manips, slot, idFrom, idTo, variant, variantTo, imcFileFrom, imcFileTo ); + swaps.Add( imc ); + } } return affectedItems; diff --git a/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs b/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs index 66ceb930..deb15bee 100644 --- a/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs +++ b/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs @@ -124,11 +124,11 @@ public class ItemSwapContainer return m => set.TryGetValue( m, out var a ) ? a : m; } - public Item[] LoadEquipment( Item from, Item to, ModCollection? collection = null ) + public Item[] LoadEquipment( Item from, Item to, ModCollection? collection = null, bool useRightRing = true, bool useLeftRing = true ) { Swaps.Clear(); Loaded = false; - var ret = EquipmentSwap.CreateItemSwap( Swaps, PathResolver( collection ), MetaResolver( collection ), from, to ); + var ret = EquipmentSwap.CreateItemSwap( Swaps, PathResolver( collection ), MetaResolver( collection ), from, to, useRightRing, useLeftRing ); Loaded = true; return ret; } diff --git a/Penumbra/UI/Classes/ItemSwapWindow.cs b/Penumbra/UI/Classes/ItemSwapWindow.cs index b086e148..69a4494c 100644 --- a/Penumbra/UI/Classes/ItemSwapWindow.cs +++ b/Penumbra/UI/Classes/ItemSwapWindow.cs @@ -109,6 +109,8 @@ public class ItemSwapWindow : IDisposable private bool _subModValid = false; private bool _useFileSwaps = true; private bool _useCurrentCollection = false; + private bool _useLeftRing = true; + private bool _useRightRing = true; private Item[]? _affectedItems; @@ -159,7 +161,7 @@ public class ItemSwapWindow : IDisposable if( values.Source.CurrentSelection.Item2 != null && values.Target.CurrentSelection.Item2 != null ) { _affectedItems = _swapData.LoadEquipment( values.Target.CurrentSelection.Item2, values.Source.CurrentSelection.Item2, - _useCurrentCollection ? Penumbra.CollectionManager.Current : null ); + _useCurrentCollection ? Penumbra.CollectionManager.Current : null, _useRightRing, _useLeftRing ); } break; @@ -399,11 +401,22 @@ public class ItemSwapWindow : IDisposable ImGui.TableNextColumn(); _dirty |= sourceSelector.Draw( "##itemSource", sourceSelector.CurrentSelection.Item1 ?? string.Empty, InputWidth * 2, ImGui.GetTextLineHeightWithSpacing() ); + if( type == SwapType.Ring ) + { + ImGui.SameLine(); + _dirty |= ImGui.Checkbox( "Swap Right Ring", ref _useRightRing ); + } + ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); ImGui.TextUnformatted( text2 ); ImGui.TableNextColumn(); _dirty |= targetSelector.Draw( "##itemTarget", targetSelector.CurrentSelection.Item1 ?? string.Empty, InputWidth * 2, ImGui.GetTextLineHeightWithSpacing() ); + if( type == SwapType.Ring ) + { + ImGui.SameLine(); + _dirty |= ImGui.Checkbox( "Swap Left Ring", ref _useLeftRing ); + } if( _affectedItems is { Length: > 1 } ) { @@ -652,7 +665,7 @@ public class ItemSwapWindow : IDisposable return; } - UpdateMod( _mod, _mod.Index < newCollection.Settings.Count ? newCollection.Settings[ _mod.Index ] : null ); + UpdateMod( _mod, _mod.Index < newCollection.Settings.Count ? newCollection.Settings[ _mod.Index ] : null ); newCollection.ModSettingChanged += OnSettingChange; if( oldCollection != null ) {