mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Add the option to omit mch offhands from changed items.
This commit is contained in:
parent
bb56faa288
commit
e85b84dafe
13 changed files with 192 additions and 117 deletions
|
|
@ -6,6 +6,7 @@ using Penumbra.Communication;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Collections.Cache;
|
namespace Penumbra.Collections.Cache;
|
||||||
|
|
||||||
|
|
@ -439,9 +440,12 @@ public sealed class CollectionCache : IDisposable
|
||||||
|
|
||||||
foreach (var (manip, mod) in Meta)
|
foreach (var (manip, mod) in Meta)
|
||||||
{
|
{
|
||||||
ModCacheManager.ComputeChangedItems(identifier, items, manip);
|
identifier.MetaChangedItems(items, manip);
|
||||||
AddItems(mod);
|
AddItems(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_manager.Config.HideMachinistOffhandFromChangedItems)
|
||||||
|
_changedItems.RemoveMachinistOffhands();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ public class CollectionCacheManager : IDisposable
|
||||||
private readonly ModStorage _modStorage;
|
private readonly ModStorage _modStorage;
|
||||||
private readonly CollectionStorage _storage;
|
private readonly CollectionStorage _storage;
|
||||||
private readonly ActiveCollections _active;
|
private readonly ActiveCollections _active;
|
||||||
|
internal readonly Configuration Config;
|
||||||
internal readonly ResolvedFileChanged ResolvedFileChanged;
|
internal readonly ResolvedFileChanged ResolvedFileChanged;
|
||||||
internal readonly MetaFileManager MetaFileManager;
|
internal readonly MetaFileManager MetaFileManager;
|
||||||
internal readonly ResourceLoader ResourceLoader;
|
internal readonly ResourceLoader ResourceLoader;
|
||||||
|
|
@ -40,7 +41,8 @@ public class CollectionCacheManager : IDisposable
|
||||||
=> _storage.Where(c => c.HasCache);
|
=> _storage.Where(c => c.HasCache);
|
||||||
|
|
||||||
public CollectionCacheManager(FrameworkManager framework, CommunicatorService communicator, TempModManager tempMods, ModStorage modStorage,
|
public CollectionCacheManager(FrameworkManager framework, CommunicatorService communicator, TempModManager tempMods, ModStorage modStorage,
|
||||||
MetaFileManager metaFileManager, ActiveCollections active, CollectionStorage storage, ResourceLoader resourceLoader)
|
MetaFileManager metaFileManager, ActiveCollections active, CollectionStorage storage, ResourceLoader resourceLoader,
|
||||||
|
Configuration config)
|
||||||
{
|
{
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
|
|
@ -50,6 +52,7 @@ public class CollectionCacheManager : IDisposable
|
||||||
_active = active;
|
_active = active;
|
||||||
_storage = storage;
|
_storage = storage;
|
||||||
ResourceLoader = resourceLoader;
|
ResourceLoader = resourceLoader;
|
||||||
|
Config = config;
|
||||||
ResolvedFileChanged = _communicator.ResolvedFileChanged;
|
ResolvedFileChanged = _communicator.ResolvedFileChanged;
|
||||||
|
|
||||||
if (!_active.Individuals.IsLoaded)
|
if (!_active.Individuals.IsLoaded)
|
||||||
|
|
@ -260,7 +263,8 @@ public class CollectionCacheManager : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Prepare Changes by removing mods from caches with collections or add or reload mods. </summary>
|
/// <summary> Prepare Changes by removing mods from caches with collections or add or reload mods. </summary>
|
||||||
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container, int movedToIdx)
|
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container,
|
||||||
|
int movedToIdx)
|
||||||
{
|
{
|
||||||
if (type is ModOptionChangeType.PrepareChange)
|
if (type is ModOptionChangeType.PrepareChange)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,18 +41,19 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public bool HideUiWhenUiHidden { get; set; } = false;
|
public bool HideUiWhenUiHidden { get; set; } = false;
|
||||||
public bool UseDalamudUiTextureRedirection { get; set; } = true;
|
public bool UseDalamudUiTextureRedirection { get; set; } = true;
|
||||||
|
|
||||||
public bool UseCharacterCollectionInMainWindow { get; set; } = true;
|
public bool UseCharacterCollectionInMainWindow { get; set; } = true;
|
||||||
public bool UseCharacterCollectionsInCards { get; set; } = true;
|
public bool UseCharacterCollectionsInCards { get; set; } = true;
|
||||||
public bool UseCharacterCollectionInInspect { get; set; } = true;
|
public bool UseCharacterCollectionInInspect { get; set; } = true;
|
||||||
public bool UseCharacterCollectionInTryOn { get; set; } = true;
|
public bool UseCharacterCollectionInTryOn { get; set; } = true;
|
||||||
public bool UseOwnerNameForCharacterCollection { get; set; } = true;
|
public bool UseOwnerNameForCharacterCollection { get; set; } = true;
|
||||||
public bool UseNoModsInInspect { get; set; } = false;
|
public bool UseNoModsInInspect { get; set; } = false;
|
||||||
public bool HideChangedItemFilters { get; set; } = false;
|
public bool HideChangedItemFilters { get; set; } = false;
|
||||||
public bool ReplaceNonAsciiOnImport { get; set; } = false;
|
public bool ReplaceNonAsciiOnImport { get; set; } = false;
|
||||||
public bool HidePrioritiesInSelector { get; set; } = false;
|
public bool HidePrioritiesInSelector { get; set; } = false;
|
||||||
public bool HideRedrawBar { get; set; } = false;
|
public bool HideRedrawBar { get; set; } = false;
|
||||||
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
|
public bool HideMachinistOffhandFromChangedItems { get; set; } = true;
|
||||||
public int OptionGroupCollapsibleMin { get; set; } = 5;
|
public RenameField ShowRename { get; set; } = RenameField.BothDataPrio;
|
||||||
|
public int OptionGroupCollapsibleMin { get; set; } = 5;
|
||||||
|
|
||||||
public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY);
|
public Vector2 MinimumSize = new(Constants.MinimumSizeX, Constants.MinimumSizeY);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
using Penumbra.Mods.SubMods;
|
using Penumbra.Mods.SubMods;
|
||||||
|
|
@ -40,6 +41,7 @@ public interface IModGroup
|
||||||
public int GetIndex();
|
public int GetIndex();
|
||||||
|
|
||||||
public void AddData(Setting setting, Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations);
|
public void AddData(Setting setting, Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations);
|
||||||
|
public void AddChangedItems(ObjectIdentification identifier, IDictionary<string, object?> changedItems);
|
||||||
|
|
||||||
/// <summary> Ensure that a value is valid for a group. </summary>
|
/// <summary> Ensure that a value is valid for a group. </summary>
|
||||||
public Setting FixSetting(Setting setting);
|
public Setting FixSetting(Setting setting);
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,14 @@ using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
using Penumbra.Mods.SubMods;
|
using Penumbra.Mods.SubMods;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Groups;
|
namespace Penumbra.Mods.Groups;
|
||||||
|
|
||||||
|
|
@ -119,6 +121,9 @@ public class ImcModGroup(Mod mod) : IModGroup
|
||||||
manipulations.Add(imc);
|
manipulations.Add(imc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddChangedItems(ObjectIdentification identifier, IDictionary<string, object?> changedItems)
|
||||||
|
=> identifier.MetaChangedItems(changedItems, GetManip(0));
|
||||||
|
|
||||||
public Setting FixSetting(Setting setting)
|
public Setting FixSetting(Setting setting)
|
||||||
=> new(setting.Value & (((1ul << OptionData.Count) - 1) | (CanBeDisabled ? 1ul << DisabledIndex : 0)));
|
=> new(setting.Value & (((1ul << OptionData.Count) - 1) | (CanBeDisabled ? 1ul << DisabledIndex : 0)));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
using Penumbra.Mods.SubMods;
|
using Penumbra.Mods.SubMods;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Groups;
|
namespace Penumbra.Mods.Groups;
|
||||||
|
|
||||||
|
|
@ -114,6 +116,12 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddChangedItems(ObjectIdentification identifier, IDictionary<string, object?> changedItems)
|
||||||
|
{
|
||||||
|
foreach (var container in DataContainers)
|
||||||
|
identifier.AddChangedItems(container, changedItems);
|
||||||
|
}
|
||||||
|
|
||||||
public void WriteJson(JsonTextWriter jWriter, JsonSerializer serializer, DirectoryInfo? basePath = null)
|
public void WriteJson(JsonTextWriter jWriter, JsonSerializer serializer, DirectoryInfo? basePath = null)
|
||||||
{
|
{
|
||||||
ModSaveGroup.WriteJsonBase(jWriter, this);
|
ModSaveGroup.WriteJsonBase(jWriter, this);
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,12 @@ using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
using Penumbra.Mods.SubMods;
|
using Penumbra.Mods.SubMods;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Groups;
|
namespace Penumbra.Mods.Groups;
|
||||||
|
|
||||||
|
|
@ -99,6 +101,12 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
||||||
OptionData[setting.AsIndex].AddDataTo(redirections, manipulations);
|
OptionData[setting.AsIndex].AddDataTo(redirections, manipulations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddChangedItems(ObjectIdentification identifier, IDictionary<string, object?> changedItems)
|
||||||
|
{
|
||||||
|
foreach (var container in DataContainers)
|
||||||
|
identifier.AddChangedItems(container, changedItems);
|
||||||
|
}
|
||||||
|
|
||||||
public Setting FixSetting(Setting setting)
|
public Setting FixSetting(Setting setting)
|
||||||
=> OptionData.Count == 0 ? Setting.Zero : new Setting(Math.Min(setting.Value, (ulong)(OptionData.Count - 1)));
|
=> OptionData.Count == 0 ? Setting.Zero : new Setting(Math.Min(setting.Value, (ulong)(OptionData.Count - 1)));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,27 @@
|
||||||
using Penumbra.Communication;
|
using Penumbra.Communication;
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
using Penumbra.Meta.Manipulations;
|
|
||||||
using Penumbra.Mods.Groups;
|
using Penumbra.Mods.Groups;
|
||||||
using Penumbra.Mods.Manager.OptionEditor;
|
using Penumbra.Mods.Manager.OptionEditor;
|
||||||
using Penumbra.Mods.SubMods;
|
using Penumbra.Mods.SubMods;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
||||||
public class ModCacheManager : IDisposable
|
public class ModCacheManager : IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly Configuration _config;
|
||||||
private readonly CommunicatorService _communicator;
|
private readonly CommunicatorService _communicator;
|
||||||
private readonly ObjectIdentification _identifier;
|
private readonly ObjectIdentification _identifier;
|
||||||
private readonly ModStorage _modManager;
|
private readonly ModStorage _modManager;
|
||||||
private bool _updatingItems = false;
|
private bool _updatingItems = false;
|
||||||
|
|
||||||
public ModCacheManager(CommunicatorService communicator, ObjectIdentification identifier, ModStorage modStorage)
|
public ModCacheManager(CommunicatorService communicator, ObjectIdentification identifier, ModStorage modStorage, Configuration config)
|
||||||
{
|
{
|
||||||
_communicator = communicator;
|
_communicator = communicator;
|
||||||
_identifier = identifier;
|
_identifier = identifier;
|
||||||
_modManager = modStorage;
|
_modManager = modStorage;
|
||||||
|
_config = config;
|
||||||
|
|
||||||
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.ModCacheManager);
|
_communicator.ModOptionChanged.Subscribe(OnModOptionChange, ModOptionChanged.Priority.ModCacheManager);
|
||||||
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModCacheManager);
|
_communicator.ModPathChanged.Subscribe(OnModPathChange, ModPathChanged.Priority.ModCacheManager);
|
||||||
|
|
@ -38,75 +39,8 @@ public class ModCacheManager : IDisposable
|
||||||
_communicator.ModDiscoveryFinished.Unsubscribe(OnModDiscoveryFinished);
|
_communicator.ModDiscoveryFinished.Unsubscribe(OnModDiscoveryFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Compute the items changed by a given meta manipulation and put them into the changedItems dictionary. </summary>
|
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container,
|
||||||
public static void ComputeChangedItems(ObjectIdentification identifier, IDictionary<string, object?> changedItems, MetaManipulation manip)
|
int fromIdx)
|
||||||
{
|
|
||||||
switch (manip.ManipulationType)
|
|
||||||
{
|
|
||||||
case MetaManipulation.Type.Imc:
|
|
||||||
switch (manip.Imc.ObjectType)
|
|
||||||
{
|
|
||||||
case ObjectType.Equipment:
|
|
||||||
case ObjectType.Accessory:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Equipment.Mtrl.Path(manip.Imc.PrimaryId, GenderRace.MidlanderMale, manip.Imc.EquipSlot, manip.Imc.Variant,
|
|
||||||
"a"));
|
|
||||||
break;
|
|
||||||
case ObjectType.Weapon:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Weapon.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a"));
|
|
||||||
break;
|
|
||||||
case ObjectType.DemiHuman:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.DemiHuman.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.EquipSlot, manip.Imc.Variant,
|
|
||||||
"a"));
|
|
||||||
break;
|
|
||||||
case ObjectType.Monster:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Monster.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case MetaManipulation.Type.Eqdp:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Equipment.Mdl.Path(manip.Eqdp.SetId, Names.CombinedRace(manip.Eqdp.Gender, manip.Eqdp.Race), manip.Eqdp.Slot));
|
|
||||||
break;
|
|
||||||
case MetaManipulation.Type.Eqp:
|
|
||||||
identifier.Identify(changedItems, GamePaths.Equipment.Mdl.Path(manip.Eqp.SetId, GenderRace.MidlanderMale, manip.Eqp.Slot));
|
|
||||||
break;
|
|
||||||
case MetaManipulation.Type.Est:
|
|
||||||
switch (manip.Est.Slot)
|
|
||||||
{
|
|
||||||
case EstManipulation.EstType.Hair:
|
|
||||||
changedItems.TryAdd($"Customization: {manip.Est.Race} {manip.Est.Gender} Hair (Hair) {manip.Est.SetId}", null);
|
|
||||||
break;
|
|
||||||
case EstManipulation.EstType.Face:
|
|
||||||
changedItems.TryAdd($"Customization: {manip.Est.Race} {manip.Est.Gender} Face (Face) {manip.Est.SetId}", null);
|
|
||||||
break;
|
|
||||||
case EstManipulation.EstType.Body:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Equipment.Mdl.Path(manip.Est.SetId, Names.CombinedRace(manip.Est.Gender, manip.Est.Race),
|
|
||||||
EquipSlot.Body));
|
|
||||||
break;
|
|
||||||
case EstManipulation.EstType.Head:
|
|
||||||
identifier.Identify(changedItems,
|
|
||||||
GamePaths.Equipment.Mdl.Path(manip.Est.SetId, Names.CombinedRace(manip.Est.Gender, manip.Est.Race),
|
|
||||||
EquipSlot.Head));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case MetaManipulation.Type.Gmp:
|
|
||||||
identifier.Identify(changedItems, GamePaths.Equipment.Mdl.Path(manip.Gmp.SetId, GenderRace.MidlanderMale, EquipSlot.Head));
|
|
||||||
break;
|
|
||||||
case MetaManipulation.Type.Rsp:
|
|
||||||
changedItems.TryAdd($"{manip.Rsp.SubRace.ToName()} {manip.Rsp.Attribute.ToFullString()}", null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnModOptionChange(ModOptionChangeType type, Mod mod, IModGroup? group, IModOption? option, IModDataContainer? container, int fromIdx)
|
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
|
@ -194,16 +128,14 @@ public class ModCacheManager : IDisposable
|
||||||
|
|
||||||
private void UpdateChangedItems(Mod mod)
|
private void UpdateChangedItems(Mod mod)
|
||||||
{
|
{
|
||||||
var changedItems = (SortedList<string, object?>)mod.ChangedItems;
|
mod.ChangedItems.Clear();
|
||||||
changedItems.Clear();
|
|
||||||
foreach (var gamePath in mod.AllDataContainers.SelectMany(m => m.Files.Keys.Concat(m.FileSwaps.Keys)))
|
|
||||||
_identifier.Identify(changedItems, gamePath.ToString());
|
|
||||||
|
|
||||||
foreach (var manip in mod.AllDataContainers.SelectMany(m => m.Manipulations))
|
_identifier.AddChangedItems(mod.Default, mod.ChangedItems);
|
||||||
ComputeChangedItems(_identifier, changedItems, manip);
|
foreach (var group in mod.Groups)
|
||||||
|
group.AddChangedItems(_identifier, mod.ChangedItems);
|
||||||
|
|
||||||
foreach(var imcGroup in mod.Groups.OfType<ImcModGroup>())
|
if (_config.HideMachinistOffhandFromChangedItems)
|
||||||
ComputeChangedItems(_identifier, changedItems, imcGroup.GetManip(0));
|
mod.ChangedItems.RemoveMachinistOffhands();
|
||||||
|
|
||||||
mod.LowerChangedItemsString = string.Join("\0", mod.ChangedItems.Keys.Select(k => k.ToLowerInvariant()));
|
mod.LowerChangedItemsString = string.Join("\0", mod.ChangedItems.Keys.Select(k => k.ToLowerInvariant()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,8 @@ using Penumbra.Mods.Editor;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
||||||
public class ModImportManager : IDisposable
|
public class ModImportManager(ModManager modManager, Configuration config, ModEditor modEditor) : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ModManager _modManager;
|
|
||||||
private readonly Configuration _config;
|
|
||||||
private readonly ModEditor _modEditor;
|
|
||||||
|
|
||||||
private readonly ConcurrentQueue<string[]> _modsToUnpack = new();
|
private readonly ConcurrentQueue<string[]> _modsToUnpack = new();
|
||||||
|
|
||||||
/// <summary> Mods need to be added thread-safely outside of iteration. </summary>
|
/// <summary> Mods need to be added thread-safely outside of iteration. </summary>
|
||||||
|
|
@ -26,13 +22,6 @@ public class ModImportManager : IDisposable
|
||||||
=> _modsToAdd;
|
=> _modsToAdd;
|
||||||
|
|
||||||
|
|
||||||
public ModImportManager(ModManager modManager, Configuration config, ModEditor modEditor)
|
|
||||||
{
|
|
||||||
_modManager = modManager;
|
|
||||||
_config = config;
|
|
||||||
_modEditor = modEditor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TryUnpacking()
|
public void TryUnpacking()
|
||||||
{
|
{
|
||||||
if (Importing || !_modsToUnpack.TryDequeue(out var newMods))
|
if (Importing || !_modsToUnpack.TryDequeue(out var newMods))
|
||||||
|
|
@ -51,7 +40,7 @@ public class ModImportManager : IDisposable
|
||||||
if (files.Length == 0)
|
if (files.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_import = new TexToolsImporter(files.Length, files, AddNewMod, _config, _modEditor, _modManager, _modEditor.Compactor);
|
_import = new TexToolsImporter(files.Length, files, AddNewMod, config, modEditor, modManager, modEditor.Compactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Importing
|
public bool Importing
|
||||||
|
|
@ -87,8 +76,8 @@ public class ModImportManager : IDisposable
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_modManager.AddMod(directory);
|
modManager.AddMod(directory);
|
||||||
mod = _modManager.LastOrDefault();
|
mod = modManager.LastOrDefault();
|
||||||
return mod != null && mod.ModPath == directory;
|
return mod != null && mod.ModPath == directory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,8 @@ public sealed class Mod : IMod
|
||||||
|
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
public readonly DefaultSubMod Default;
|
public readonly DefaultSubMod Default;
|
||||||
public readonly List<IModGroup> Groups = [];
|
public readonly List<IModGroup> Groups = [];
|
||||||
|
|
||||||
public AppliedModData GetData(ModSettings? settings = null)
|
public AppliedModData GetData(ModSettings? settings = null)
|
||||||
{
|
{
|
||||||
|
|
@ -99,7 +99,7 @@ public sealed class Mod : IMod
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
public readonly IReadOnlyDictionary<string, object?> ChangedItems = new SortedList<string, object?>();
|
public readonly SortedList<string, object?> ChangedItems = new();
|
||||||
|
|
||||||
public string LowerChangedItemsString { get; internal set; } = string.Empty;
|
public string LowerChangedItemsString { get; internal set; } = string.Empty;
|
||||||
public string AllTagsLower { get; internal set; } = string.Empty;
|
public string AllTagsLower { get; internal set; } = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -123,8 +123,7 @@ public sealed class ModGroupEditDrawer(
|
||||||
ModManager modManager,
|
ModManager modManager,
|
||||||
Configuration config,
|
Configuration config,
|
||||||
FilenameService filenames,
|
FilenameService filenames,
|
||||||
DescriptionEditPopup descriptionPopup,
|
DescriptionEditPopup descriptionPopup) : IUiService
|
||||||
MetaFileManager metaManager) : IUiService
|
|
||||||
{
|
{
|
||||||
private static ReadOnlySpan<byte> DragDropLabel
|
private static ReadOnlySpan<byte> DragDropLabel
|
||||||
=> "##DragOption"u8;
|
=> "##DragOption"u8;
|
||||||
|
|
|
||||||
|
|
@ -428,6 +428,14 @@ public class SettingsTab : ITab
|
||||||
_config.Ephemeral.Save();
|
_config.Ephemeral.Save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Checkbox("Omit Machinist Offhands in Changed Items",
|
||||||
|
"Omits all Aetherotransformers (machinist offhands) in the changed items tabs because any change on them changes all of them at the moment.\n\n"
|
||||||
|
+ "Changing this triggers a rediscovery of your mods so all changed items can be updated.",
|
||||||
|
_config.HideMachinistOffhandFromChangedItems, v =>
|
||||||
|
{
|
||||||
|
_config.HideMachinistOffhandFromChangedItems = v;
|
||||||
|
_modManager.DiscoverMods();
|
||||||
|
});
|
||||||
Checkbox("Hide Priority Numbers in Mod Selector",
|
Checkbox("Hide Priority Numbers in Mod Selector",
|
||||||
"Hides the bracketed non-zero priority numbers displayed in the mod selector when there is enough space for them.",
|
"Hides the bracketed non-zero priority numbers displayed in the mod selector when there is enough space for them.",
|
||||||
_config.HidePrioritiesInSelector, v => _config.HidePrioritiesInSelector = v);
|
_config.HidePrioritiesInSelector, v => _config.HidePrioritiesInSelector = v);
|
||||||
|
|
|
||||||
115
Penumbra/Util/IdentifierExtensions.cs
Normal file
115
Penumbra/Util/IdentifierExtensions.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
using OtterGui.Classes;
|
||||||
|
using Penumbra.GameData.Data;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
using Penumbra.GameData.Structs;
|
||||||
|
using Penumbra.Meta.Manipulations;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
|
using Penumbra.Mods.SubMods;
|
||||||
|
|
||||||
|
namespace Penumbra.Util;
|
||||||
|
|
||||||
|
public static class IdentifierExtensions
|
||||||
|
{
|
||||||
|
/// <summary> Compute the items changed by a given meta manipulation and put them into the changedItems dictionary. </summary>
|
||||||
|
public static void MetaChangedItems(this ObjectIdentification identifier, IDictionary<string, object?> changedItems,
|
||||||
|
MetaManipulation manip)
|
||||||
|
{
|
||||||
|
switch (manip.ManipulationType)
|
||||||
|
{
|
||||||
|
case MetaManipulation.Type.Imc:
|
||||||
|
switch (manip.Imc.ObjectType)
|
||||||
|
{
|
||||||
|
case ObjectType.Equipment:
|
||||||
|
case ObjectType.Accessory:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Equipment.Mtrl.Path(manip.Imc.PrimaryId, GenderRace.MidlanderMale, manip.Imc.EquipSlot, manip.Imc.Variant,
|
||||||
|
"a"));
|
||||||
|
break;
|
||||||
|
case ObjectType.Weapon:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Weapon.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a"));
|
||||||
|
break;
|
||||||
|
case ObjectType.DemiHuman:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.DemiHuman.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.EquipSlot, manip.Imc.Variant,
|
||||||
|
"a"));
|
||||||
|
break;
|
||||||
|
case ObjectType.Monster:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Monster.Mtrl.Path(manip.Imc.PrimaryId, manip.Imc.SecondaryId, manip.Imc.Variant, "a"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MetaManipulation.Type.Eqdp:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Equipment.Mdl.Path(manip.Eqdp.SetId, Names.CombinedRace(manip.Eqdp.Gender, manip.Eqdp.Race), manip.Eqdp.Slot));
|
||||||
|
break;
|
||||||
|
case MetaManipulation.Type.Eqp:
|
||||||
|
identifier.Identify(changedItems, GamePaths.Equipment.Mdl.Path(manip.Eqp.SetId, GenderRace.MidlanderMale, manip.Eqp.Slot));
|
||||||
|
break;
|
||||||
|
case MetaManipulation.Type.Est:
|
||||||
|
switch (manip.Est.Slot)
|
||||||
|
{
|
||||||
|
case EstManipulation.EstType.Hair:
|
||||||
|
changedItems.TryAdd($"Customization: {manip.Est.Race} {manip.Est.Gender} Hair (Hair) {manip.Est.SetId}", null);
|
||||||
|
break;
|
||||||
|
case EstManipulation.EstType.Face:
|
||||||
|
changedItems.TryAdd($"Customization: {manip.Est.Race} {manip.Est.Gender} Face (Face) {manip.Est.SetId}", null);
|
||||||
|
break;
|
||||||
|
case EstManipulation.EstType.Body:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Equipment.Mdl.Path(manip.Est.SetId, Names.CombinedRace(manip.Est.Gender, manip.Est.Race),
|
||||||
|
EquipSlot.Body));
|
||||||
|
break;
|
||||||
|
case EstManipulation.EstType.Head:
|
||||||
|
identifier.Identify(changedItems,
|
||||||
|
GamePaths.Equipment.Mdl.Path(manip.Est.SetId, Names.CombinedRace(manip.Est.Gender, manip.Est.Race),
|
||||||
|
EquipSlot.Head));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MetaManipulation.Type.Gmp:
|
||||||
|
identifier.Identify(changedItems, GamePaths.Equipment.Mdl.Path(manip.Gmp.SetId, GenderRace.MidlanderMale, EquipSlot.Head));
|
||||||
|
break;
|
||||||
|
case MetaManipulation.Type.Rsp:
|
||||||
|
changedItems.TryAdd($"{manip.Rsp.SubRace.ToName()} {manip.Rsp.Attribute.ToFullString()}", null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddChangedItems(this ObjectIdentification identifier, IModDataContainer container,
|
||||||
|
IDictionary<string, object?> changedItems)
|
||||||
|
{
|
||||||
|
foreach (var gamePath in container.Files.Keys.Concat(container.FileSwaps.Keys))
|
||||||
|
identifier.Identify(changedItems, gamePath.ToString());
|
||||||
|
|
||||||
|
foreach (var manip in container.Manipulations)
|
||||||
|
MetaChangedItems(identifier, changedItems, manip);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveMachinistOffhands(this SortedList<string, object?> changedItems)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < changedItems.Count; i++)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
var value = changedItems.Values[i];
|
||||||
|
if (value is EquipItem { Type: FullEquipType.GunOff })
|
||||||
|
changedItems.RemoveAt(i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveMachinistOffhands(this SortedList<string, (SingleArray<IMod>, object?)> changedItems)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < changedItems.Count; i++)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
var value = changedItems.Values[i].Item2;
|
||||||
|
if (value is EquipItem { Type: FullEquipType.GunOff })
|
||||||
|
changedItems.RemoveAt(i--);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue