mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 20:54:16 +01:00
Remove ISubMod.
This commit is contained in:
parent
8fc7de64d9
commit
9f4c6767f8
23 changed files with 123 additions and 184 deletions
|
|
@ -152,7 +152,7 @@ public partial class TexToolsImporter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through all pages
|
// Iterate through all pages
|
||||||
var options = new List<ISubMod>();
|
var options = new List<SubMod>();
|
||||||
var groupPriority = ModPriority.Default;
|
var groupPriority = ModPriority.Default;
|
||||||
var groupNames = new HashSet<string>();
|
var groupNames = new HashSet<string>();
|
||||||
foreach (var page in modList.ModPackPages)
|
foreach (var page in modList.ModPackPages)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public class DuplicateManager(ModManager modManager, SaveService saveService, Co
|
||||||
Worker = Task.Run(() => CheckDuplicates(filesTmp, _cancellationTokenSource.Token), _cancellationTokenSource.Token);
|
Worker = Task.Run(() => CheckDuplicates(filesTmp, _cancellationTokenSource.Token), _cancellationTokenSource.Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteDuplicates(ModFileCollection files, Mod mod, ISubMod option, bool useModManager)
|
public void DeleteDuplicates(ModFileCollection files, Mod mod, SubMod option, bool useModManager)
|
||||||
{
|
{
|
||||||
if (!Worker.IsCompleted || _duplicates.Count == 0)
|
if (!Worker.IsCompleted || _duplicates.Count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
@ -72,7 +72,7 @@ public class DuplicateManager(ModManager modManager, SaveService saveService, Co
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void HandleSubMod(ISubMod subMod, int groupIdx, int optionIdx)
|
void HandleSubMod(SubMod subMod, int groupIdx, int optionIdx)
|
||||||
{
|
{
|
||||||
var changes = false;
|
var changes = false;
|
||||||
var dict = subMod.Files.ToDictionary(kvp => kvp.Key,
|
var dict = subMod.Files.ToDictionary(kvp => kvp.Key,
|
||||||
|
|
@ -86,8 +86,7 @@ public class DuplicateManager(ModManager modManager, SaveService saveService, Co
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var sub = (SubMod)subMod;
|
subMod.FileData = dict;
|
||||||
sub.FileData = dict;
|
|
||||||
saveService.ImmediateSaveSync(new ModSaveGroup(mod, groupIdx, config.ReplaceNonAsciiOnImport));
|
saveService.ImmediateSaveSync(new ModSaveGroup(mod, groupIdx, config.ReplaceNonAsciiOnImport));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Penumbra.Mods.Editor;
|
||||||
|
|
||||||
public class FileRegistry : IEquatable<FileRegistry>
|
public class FileRegistry : IEquatable<FileRegistry>
|
||||||
{
|
{
|
||||||
public readonly List<(ISubMod, Utf8GamePath)> SubModUsage = [];
|
public readonly List<(SubMod, Utf8GamePath)> SubModUsage = [];
|
||||||
public FullPath File { get; private init; }
|
public FullPath File { get; private init; }
|
||||||
public Utf8RelPath RelPath { get; private init; }
|
public Utf8RelPath RelPath { get; private init; }
|
||||||
public long FileSize { get; private init; }
|
public long FileSize { get; private init; }
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ using Penumbra.String.Classes;
|
||||||
namespace Penumbra.Mods.Editor;
|
namespace Penumbra.Mods.Editor;
|
||||||
|
|
||||||
public record struct AppliedModData(
|
public record struct AppliedModData(
|
||||||
IReadOnlyCollection<KeyValuePair<Utf8GamePath, FullPath>> FileRedirections,
|
Dictionary<Utf8GamePath, FullPath> FileRedirections,
|
||||||
IReadOnlyCollection<MetaManipulation> Manipulations)
|
HashSet<MetaManipulation> Manipulations)
|
||||||
{
|
{
|
||||||
public static readonly AppliedModData Empty = new([], []);
|
public static readonly AppliedModData Empty = new([], []);
|
||||||
}
|
}
|
||||||
|
|
@ -19,13 +19,9 @@ public interface IMod
|
||||||
public int Index { get; }
|
public int Index { get; }
|
||||||
public ModPriority Priority { get; }
|
public ModPriority Priority { get; }
|
||||||
|
|
||||||
public AppliedModData GetData(ModSettings? settings = null);
|
|
||||||
|
|
||||||
|
|
||||||
public ISubMod Default { get; }
|
|
||||||
public IReadOnlyList<IModGroup> Groups { get; }
|
public IReadOnlyList<IModGroup> Groups { get; }
|
||||||
|
|
||||||
public IEnumerable<SubMod> AllSubMods { get; }
|
public AppliedModData GetData(ModSettings? settings = null);
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
public int TotalManipulations { get; }
|
public int TotalManipulations { get; }
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public class ModEditor(
|
||||||
public int OptionIdx { get; private set; }
|
public int OptionIdx { get; private set; }
|
||||||
|
|
||||||
public IModGroup? Group { get; private set; }
|
public IModGroup? Group { get; private set; }
|
||||||
public ISubMod? Option { get; private set; }
|
public SubMod? Option { get; private set; }
|
||||||
|
|
||||||
public void LoadMod(Mod mod)
|
public void LoadMod(Mod mod)
|
||||||
=> LoadMod(mod, -1, 0);
|
=> LoadMod(mod, -1, 0);
|
||||||
|
|
@ -104,7 +104,7 @@ public class ModEditor(
|
||||||
=> Clear();
|
=> Clear();
|
||||||
|
|
||||||
/// <summary> Apply a option action to all available option in a mod, including the default option. </summary>
|
/// <summary> Apply a option action to all available option in a mod, including the default option. </summary>
|
||||||
public static void ApplyToAllOptions(Mod mod, Action<ISubMod, int, int> action)
|
public static void ApplyToAllOptions(Mod mod, Action<SubMod, int, int> action)
|
||||||
{
|
{
|
||||||
action(mod.Default, -1, 0);
|
action(mod.Default, -1, 0);
|
||||||
foreach (var (group, groupIdx) in mod.Groups.WithIndex())
|
foreach (var (group, groupIdx) in mod.Groups.WithIndex())
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,13 @@ public class ModFileCollection : IDisposable
|
||||||
|
|
||||||
public bool Ready { get; private set; } = true;
|
public bool Ready { get; private set; } = true;
|
||||||
|
|
||||||
public void UpdateAll(Mod mod, ISubMod option)
|
public void UpdateAll(Mod mod, SubMod option)
|
||||||
{
|
{
|
||||||
UpdateFiles(mod, new CancellationToken());
|
UpdateFiles(mod, new CancellationToken());
|
||||||
UpdatePaths(mod, option, false, new CancellationToken());
|
UpdatePaths(mod, option, false, new CancellationToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdatePaths(Mod mod, ISubMod option)
|
public void UpdatePaths(Mod mod, SubMod option)
|
||||||
=> UpdatePaths(mod, option, true, new CancellationToken());
|
=> UpdatePaths(mod, option, true, new CancellationToken());
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
|
|
@ -59,7 +59,7 @@ public class ModFileCollection : IDisposable
|
||||||
public void ClearMissingFiles()
|
public void ClearMissingFiles()
|
||||||
=> _missing.Clear();
|
=> _missing.Clear();
|
||||||
|
|
||||||
public void RemoveUsedPath(ISubMod option, FileRegistry? file, Utf8GamePath gamePath)
|
public void RemoveUsedPath(SubMod option, FileRegistry? file, Utf8GamePath gamePath)
|
||||||
{
|
{
|
||||||
_usedPaths.Remove(gamePath);
|
_usedPaths.Remove(gamePath);
|
||||||
if (file != null)
|
if (file != null)
|
||||||
|
|
@ -69,10 +69,10 @@ public class ModFileCollection : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveUsedPath(ISubMod option, FullPath file, Utf8GamePath gamePath)
|
public void RemoveUsedPath(SubMod option, FullPath file, Utf8GamePath gamePath)
|
||||||
=> RemoveUsedPath(option, _available.FirstOrDefault(f => f.File.Equals(file)), gamePath);
|
=> RemoveUsedPath(option, _available.FirstOrDefault(f => f.File.Equals(file)), gamePath);
|
||||||
|
|
||||||
public void AddUsedPath(ISubMod option, FileRegistry? file, Utf8GamePath gamePath)
|
public void AddUsedPath(SubMod option, FileRegistry? file, Utf8GamePath gamePath)
|
||||||
{
|
{
|
||||||
_usedPaths.Add(gamePath);
|
_usedPaths.Add(gamePath);
|
||||||
if (file == null)
|
if (file == null)
|
||||||
|
|
@ -82,7 +82,7 @@ public class ModFileCollection : IDisposable
|
||||||
file.SubModUsage.Add((option, gamePath));
|
file.SubModUsage.Add((option, gamePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddUsedPath(ISubMod option, FullPath file, Utf8GamePath gamePath)
|
public void AddUsedPath(SubMod option, FullPath file, Utf8GamePath gamePath)
|
||||||
=> AddUsedPath(option, _available.FirstOrDefault(f => f.File.Equals(file)), gamePath);
|
=> AddUsedPath(option, _available.FirstOrDefault(f => f.File.Equals(file)), gamePath);
|
||||||
|
|
||||||
public void ChangeUsedPath(FileRegistry file, int pathIdx, Utf8GamePath gamePath)
|
public void ChangeUsedPath(FileRegistry file, int pathIdx, Utf8GamePath gamePath)
|
||||||
|
|
@ -154,7 +154,7 @@ public class ModFileCollection : IDisposable
|
||||||
_usedPaths.Clear();
|
_usedPaths.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePaths(Mod mod, ISubMod option, bool clearRegistries, CancellationToken tok)
|
private void UpdatePaths(Mod mod, SubMod option, bool clearRegistries, CancellationToken tok)
|
||||||
{
|
{
|
||||||
tok.ThrowIfCancellationRequested();
|
tok.ThrowIfCancellationRequested();
|
||||||
ClearPaths(clearRegistries, tok);
|
ClearPaths(clearRegistries, tok);
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,16 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Revert(Mod mod, ISubMod option)
|
public void Revert(Mod mod, SubMod option)
|
||||||
{
|
{
|
||||||
files.UpdateAll(mod, option);
|
files.UpdateAll(mod, option);
|
||||||
Changes = false;
|
Changes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Remove all path redirections where the pointed-to file does not exist. </summary>
|
/// <summary> Remove all path redirections where the pointed-to file does not exist. </summary>
|
||||||
public void RemoveMissingPaths(Mod mod, ISubMod option)
|
public void RemoveMissingPaths(Mod mod, SubMod option)
|
||||||
{
|
{
|
||||||
void HandleSubMod(ISubMod subMod, int groupIdx, int optionIdx)
|
void HandleSubMod(SubMod subMod, int groupIdx, int optionIdx)
|
||||||
{
|
{
|
||||||
var newDict = subMod.Files.Where(kvp => CheckAgainstMissing(mod, subMod, kvp.Value, kvp.Key, subMod == option))
|
var newDict = subMod.Files.Where(kvp => CheckAgainstMissing(mod, subMod, kvp.Value, kvp.Key, subMod == option))
|
||||||
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
|
|
@ -61,7 +61,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
/// If path is empty, it will be deleted instead.
|
/// If path is empty, it will be deleted instead.
|
||||||
/// If pathIdx is equal to the total number of paths, path will be added, otherwise replaced.
|
/// If pathIdx is equal to the total number of paths, path will be added, otherwise replaced.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SetGamePath(ISubMod option, int fileIdx, int pathIdx, Utf8GamePath path)
|
public bool SetGamePath(SubMod option, int fileIdx, int pathIdx, Utf8GamePath path)
|
||||||
{
|
{
|
||||||
if (!CanAddGamePath(path) || fileIdx < 0 || fileIdx > files.Available.Count)
|
if (!CanAddGamePath(path) || fileIdx < 0 || fileIdx > files.Available.Count)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -84,7 +84,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
/// Transform a set of files to the appropriate game paths with the given number of folders skipped,
|
/// Transform a set of files to the appropriate game paths with the given number of folders skipped,
|
||||||
/// and add them to the given option.
|
/// and add them to the given option.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AddPathsToSelected(ISubMod option, IEnumerable<FileRegistry> files1, int skipFolders = 0)
|
public int AddPathsToSelected(SubMod option, IEnumerable<FileRegistry> files1, int skipFolders = 0)
|
||||||
{
|
{
|
||||||
var failed = 0;
|
var failed = 0;
|
||||||
foreach (var file in files1)
|
foreach (var file in files1)
|
||||||
|
|
@ -111,7 +111,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Remove all paths in the current option from the given files. </summary>
|
/// <summary> Remove all paths in the current option from the given files. </summary>
|
||||||
public void RemovePathsFromSelected(ISubMod option, IEnumerable<FileRegistry> files1)
|
public void RemovePathsFromSelected(SubMod option, IEnumerable<FileRegistry> files1)
|
||||||
{
|
{
|
||||||
foreach (var file in files1)
|
foreach (var file in files1)
|
||||||
{
|
{
|
||||||
|
|
@ -129,7 +129,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Delete all given files from your filesystem </summary>
|
/// <summary> Delete all given files from your filesystem </summary>
|
||||||
public void DeleteFiles(Mod mod, ISubMod option, IEnumerable<FileRegistry> files1)
|
public void DeleteFiles(Mod mod, SubMod option, IEnumerable<FileRegistry> files1)
|
||||||
{
|
{
|
||||||
var deletions = 0;
|
var deletions = 0;
|
||||||
foreach (var file in files1)
|
foreach (var file in files1)
|
||||||
|
|
@ -155,7 +155,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool CheckAgainstMissing(Mod mod, ISubMod option, FullPath file, Utf8GamePath key, bool removeUsed)
|
private bool CheckAgainstMissing(Mod mod, SubMod option, FullPath file, Utf8GamePath key, bool removeUsed)
|
||||||
{
|
{
|
||||||
if (!files.Missing.Contains(file))
|
if (!files.Missing.Contains(file))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ public class ModMerger : IDisposable
|
||||||
MergeIntoOption(MergeFromMod!.AllSubMods.Reverse(), option, true);
|
MergeIntoOption(MergeFromMod!.AllSubMods.Reverse(), option, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MergeIntoOption(IEnumerable<ISubMod> mergeOptions, SubMod option, bool fromFileToFile)
|
private void MergeIntoOption(IEnumerable<SubMod> mergeOptions, SubMod option, bool fromFileToFile)
|
||||||
{
|
{
|
||||||
var redirections = option.FileData.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
var redirections = option.FileData.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
var swaps = option.FileSwapData.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
var swaps = option.FileSwapData.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public class ModMetaEditor(ModManager modManager)
|
||||||
Changes = true;
|
Changes = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(Mod mod, ISubMod currentOption)
|
public void Load(Mod mod, SubMod currentOption)
|
||||||
{
|
{
|
||||||
OtherImcCount = 0;
|
OtherImcCount = 0;
|
||||||
OtherEqpCount = 0;
|
OtherEqpCount = 0;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public class ModSwapEditor(ModManager modManager)
|
||||||
public IReadOnlyDictionary<Utf8GamePath, FullPath> Swaps
|
public IReadOnlyDictionary<Utf8GamePath, FullPath> Swaps
|
||||||
=> _swaps;
|
=> _swaps;
|
||||||
|
|
||||||
public void Revert(ISubMod option)
|
public void Revert(SubMod option)
|
||||||
{
|
{
|
||||||
_swaps.SetTo(option.FileSwaps);
|
_swaps.SetTo(option.FileSwaps);
|
||||||
Changes = false;
|
Changes = false;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Penumbra.GameData.Structs;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Mods.Subclasses;
|
using Penumbra.Mods.Subclasses;
|
||||||
|
|
||||||
|
|
@ -15,14 +16,13 @@ public class ItemSwapContainer
|
||||||
private readonly MetaFileManager _manager;
|
private readonly MetaFileManager _manager;
|
||||||
private readonly ObjectIdentification _identifier;
|
private readonly ObjectIdentification _identifier;
|
||||||
|
|
||||||
private Dictionary<Utf8GamePath, FullPath> _modRedirections = [];
|
private AppliedModData _appliedModData = AppliedModData.Empty;
|
||||||
private HashSet<MetaManipulation> _modManipulations = [];
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<Utf8GamePath, FullPath> ModRedirections
|
public IReadOnlyDictionary<Utf8GamePath, FullPath> ModRedirections
|
||||||
=> _modRedirections;
|
=> _appliedModData.FileRedirections;
|
||||||
|
|
||||||
public IReadOnlySet<MetaManipulation> ModManipulations
|
public IReadOnlySet<MetaManipulation> ModManipulations
|
||||||
=> _modManipulations;
|
=> _appliedModData.Manipulations;
|
||||||
|
|
||||||
public readonly List<Swap> Swaps = [];
|
public readonly List<Swap> Swaps = [];
|
||||||
|
|
||||||
|
|
@ -97,12 +97,11 @@ public class ItemSwapContainer
|
||||||
Clear();
|
Clear();
|
||||||
if (mod == null || mod.Index < 0)
|
if (mod == null || mod.Index < 0)
|
||||||
{
|
{
|
||||||
_modRedirections = [];
|
_appliedModData = AppliedModData.Empty;
|
||||||
_modManipulations = [];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(_modRedirections, _modManipulations) = ModSettings.GetResolveData(mod, settings);
|
_appliedModData = ModSettings.GetResolveData(mod, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,7 +119,7 @@ public class ItemSwapContainer
|
||||||
|
|
||||||
private Func<MetaManipulation, MetaManipulation> MetaResolver(ModCollection? collection)
|
private Func<MetaManipulation, MetaManipulation> MetaResolver(ModCollection? collection)
|
||||||
{
|
{
|
||||||
var set = collection?.MetaCache?.Manipulations.ToHashSet() ?? _modManipulations;
|
var set = collection?.MetaCache?.Manipulations.ToHashSet() ?? _appliedModData.Manipulations;
|
||||||
return m => set.TryGetValue(m, out var a) ? a : m;
|
return m => set.TryGetValue(m, out var a) ? a : m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -262,15 +262,12 @@ public class ModOptionEditor(CommunicatorService communicator, SaveService saveS
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Add an existing option to a given group with default priority. </summary>
|
/// <summary> Add an existing option to a given group with default priority. </summary>
|
||||||
public void AddOption(Mod mod, int groupIdx, ISubMod option)
|
public void AddOption(Mod mod, int groupIdx, SubMod option)
|
||||||
=> AddOption(mod, groupIdx, option, ModPriority.Default);
|
=> AddOption(mod, groupIdx, option, ModPriority.Default);
|
||||||
|
|
||||||
/// <summary> Add an existing option to a given group with a given priority. </summary>
|
/// <summary> Add an existing option to a given group with a given priority. </summary>
|
||||||
public void AddOption(Mod mod, int groupIdx, ISubMod option, ModPriority priority)
|
public void AddOption(Mod mod, int groupIdx, SubMod option, ModPriority priority)
|
||||||
{
|
{
|
||||||
if (option is not SubMod o)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var group = mod.Groups[groupIdx];
|
var group = mod.Groups[groupIdx];
|
||||||
switch (group)
|
switch (group)
|
||||||
{
|
{
|
||||||
|
|
@ -280,12 +277,12 @@ public class ModOptionEditor(CommunicatorService communicator, SaveService saveS
|
||||||
+ $"since only up to {IModGroup.MaxMultiOptions} options are supported in one group.");
|
+ $"since only up to {IModGroup.MaxMultiOptions} options are supported in one group.");
|
||||||
return;
|
return;
|
||||||
case SingleModGroup s:
|
case SingleModGroup s:
|
||||||
o.SetPosition(groupIdx, s.Count);
|
option.SetPosition(groupIdx, s.Count);
|
||||||
s.OptionData.Add(o);
|
s.OptionData.Add(option);
|
||||||
break;
|
break;
|
||||||
case MultiModGroup m:
|
case MultiModGroup m:
|
||||||
o.SetPosition(groupIdx, m.Count);
|
option.SetPosition(groupIdx, m.Count);
|
||||||
m.PrioritizedOptions.Add((o, priority));
|
m.PrioritizedOptions.Add((option, priority));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ public sealed class Mod : IMod
|
||||||
public ModPriority Priority
|
public ModPriority Priority
|
||||||
=> ModPriority.Default;
|
=> ModPriority.Default;
|
||||||
|
|
||||||
|
IReadOnlyList<IModGroup> IMod.Groups
|
||||||
|
=> Groups;
|
||||||
|
|
||||||
internal Mod(DirectoryInfo modPath)
|
internal Mod(DirectoryInfo modPath)
|
||||||
{
|
{
|
||||||
ModPath = modPath;
|
ModPath = modPath;
|
||||||
|
|
@ -74,18 +77,12 @@ public sealed class Mod : IMod
|
||||||
group.AddData(config, dictRedirections, setManips);
|
group.AddData(config, dictRedirections, setManips);
|
||||||
}
|
}
|
||||||
|
|
||||||
((ISubMod)Default).AddData(dictRedirections, setManips);
|
Default.AddData(dictRedirections, setManips);
|
||||||
return new AppliedModData(dictRedirections, setManips);
|
return new AppliedModData(dictRedirections, setManips);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISubMod IMod.Default
|
|
||||||
=> Default;
|
|
||||||
|
|
||||||
IReadOnlyList<IModGroup> IMod.Groups
|
|
||||||
=> Groups;
|
|
||||||
|
|
||||||
public IEnumerable<SubMod> AllSubMods
|
public IEnumerable<SubMod> AllSubMods
|
||||||
=> Groups.SelectMany(o => o).OfType<SubMod>().Prepend(Default);
|
=> Groups.SelectMany(o => o).Prepend(Default);
|
||||||
|
|
||||||
public List<FullPath> FindUnusedFiles()
|
public List<FullPath> FindUnusedFiles()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ public partial class ModCreator(SaveService _saveService, Configuration config,
|
||||||
|
|
||||||
/// <summary> Create a file for an option group from given data. </summary>
|
/// <summary> Create a file for an option group from given data. </summary>
|
||||||
public void CreateOptionGroup(DirectoryInfo baseFolder, GroupType type, string name,
|
public void CreateOptionGroup(DirectoryInfo baseFolder, GroupType type, string name,
|
||||||
ModPriority priority, int index, Setting defaultSettings, string desc, IEnumerable<ISubMod> subMods)
|
ModPriority priority, int index, Setting defaultSettings, string desc, IEnumerable<SubMod> subMods)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
|
@ -248,7 +248,7 @@ public partial class ModCreator(SaveService _saveService, Configuration config,
|
||||||
Priority = priority,
|
Priority = priority,
|
||||||
DefaultSettings = defaultSettings,
|
DefaultSettings = defaultSettings,
|
||||||
};
|
};
|
||||||
group.PrioritizedOptions.AddRange(subMods.OfType<SubMod>().Select((s, idx) => (s, new ModPriority(idx))));
|
group.PrioritizedOptions.AddRange(subMods.Select((s, idx) => (s, new ModPriority(idx))));
|
||||||
_saveService.ImmediateSaveSync(new ModSaveGroup(baseFolder, group, index, Config.ReplaceNonAsciiOnImport));
|
_saveService.ImmediateSaveSync(new ModSaveGroup(baseFolder, group, index, Config.ReplaceNonAsciiOnImport));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +269,7 @@ public partial class ModCreator(SaveService _saveService, Configuration config,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Create the data for a given sub mod from its data and the folder it is based on. </summary>
|
/// <summary> Create the data for a given sub mod from its data and the folder it is based on. </summary>
|
||||||
public ISubMod CreateSubMod(DirectoryInfo baseFolder, DirectoryInfo optionFolder, OptionList option)
|
public SubMod CreateSubMod(DirectoryInfo baseFolder, DirectoryInfo optionFolder, OptionList option)
|
||||||
{
|
{
|
||||||
var list = optionFolder.EnumerateNonHiddenFiles()
|
var list = optionFolder.EnumerateNonHiddenFiles()
|
||||||
.Select(f => (Utf8GamePath.FromFile(f, optionFolder, out var gamePath, true), gamePath, new FullPath(f)))
|
.Select(f => (Utf8GamePath.FromFile(f, optionFolder, out var gamePath, true), gamePath, new FullPath(f)))
|
||||||
|
|
@ -288,7 +288,7 @@ public partial class ModCreator(SaveService _saveService, Configuration config,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Create an empty sub mod for single groups with None options. </summary>
|
/// <summary> Create an empty sub mod for single groups with None options. </summary>
|
||||||
internal static ISubMod CreateEmptySubMod(string name)
|
internal static SubMod CreateEmptySubMod(string name)
|
||||||
=> new SubMod(null!) // Mod is irrelevant here, only used for saving.
|
=> new SubMod(null!) // Mod is irrelevant here, only used for saving.
|
||||||
{
|
{
|
||||||
Name = name,
|
Name = name,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Subclasses;
|
namespace Penumbra.Mods.Subclasses;
|
||||||
|
|
||||||
public interface IModGroup : IReadOnlyCollection<ISubMod>
|
public interface IModGroup : IReadOnlyCollection<SubMod>
|
||||||
{
|
{
|
||||||
public const int MaxMultiOptions = 63;
|
public const int MaxMultiOptions = 63;
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@ public interface IModGroup : IReadOnlyCollection<ISubMod>
|
||||||
|
|
||||||
public ModPriority OptionPriority(Index optionIdx);
|
public ModPriority OptionPriority(Index optionIdx);
|
||||||
|
|
||||||
public ISubMod this[Index idx] { get; }
|
public SubMod this[Index idx] { get; }
|
||||||
|
|
||||||
public bool IsOption { get; }
|
public bool IsOption { get; }
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ public readonly struct ModSaveGroup : ISavable
|
||||||
private readonly DirectoryInfo _basePath;
|
private readonly DirectoryInfo _basePath;
|
||||||
private readonly IModGroup? _group;
|
private readonly IModGroup? _group;
|
||||||
private readonly int _groupIdx;
|
private readonly int _groupIdx;
|
||||||
private readonly ISubMod? _defaultMod;
|
private readonly SubMod? _defaultMod;
|
||||||
private readonly bool _onlyAscii;
|
private readonly bool _onlyAscii;
|
||||||
|
|
||||||
public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii)
|
public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii)
|
||||||
|
|
@ -59,7 +59,7 @@ public readonly struct ModSaveGroup : ISavable
|
||||||
_onlyAscii = onlyAscii;
|
_onlyAscii = onlyAscii;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModSaveGroup(DirectoryInfo basePath, ISubMod @default, bool onlyAscii)
|
public ModSaveGroup(DirectoryInfo basePath, SubMod @default, bool onlyAscii)
|
||||||
{
|
{
|
||||||
_basePath = basePath;
|
_basePath = basePath;
|
||||||
_groupIdx = -1;
|
_groupIdx = -1;
|
||||||
|
|
@ -91,7 +91,7 @@ public readonly struct ModSaveGroup : ISavable
|
||||||
j.WriteStartArray();
|
j.WriteStartArray();
|
||||||
for (var idx = 0; idx < _group.Count; ++idx)
|
for (var idx = 0; idx < _group.Count; ++idx)
|
||||||
{
|
{
|
||||||
ISubMod.WriteSubMod(j, serializer, _group[idx], _basePath, _group.Type switch
|
SubMod.WriteSubMod(j, serializer, _group[idx], _basePath, _group.Type switch
|
||||||
{
|
{
|
||||||
GroupType.Multi => _group.OptionPriority(idx),
|
GroupType.Multi => _group.OptionPriority(idx),
|
||||||
_ => null,
|
_ => null,
|
||||||
|
|
@ -103,7 +103,7 @@ public readonly struct ModSaveGroup : ISavable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ISubMod.WriteSubMod(j, serializer, _defaultMod!, _basePath, null);
|
SubMod.WriteSubMod(j, serializer, _defaultMod!, _basePath, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Penumbra.Meta.Manipulations;
|
|
||||||
using Penumbra.String.Classes;
|
|
||||||
|
|
||||||
namespace Penumbra.Mods.Subclasses;
|
|
||||||
|
|
||||||
public interface ISubMod
|
|
||||||
{
|
|
||||||
public string Name { get; }
|
|
||||||
public string FullName { get; }
|
|
||||||
public string Description { get; }
|
|
||||||
|
|
||||||
public IReadOnlyDictionary<Utf8GamePath, FullPath> Files { get; }
|
|
||||||
public IReadOnlyDictionary<Utf8GamePath, FullPath> FileSwaps { get; }
|
|
||||||
public IReadOnlySet<MetaManipulation> Manipulations { get; }
|
|
||||||
|
|
||||||
public void AddData(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
|
||||||
{
|
|
||||||
foreach (var (path, file) in Files)
|
|
||||||
redirections.TryAdd(path, file);
|
|
||||||
|
|
||||||
foreach (var (path, file) in FileSwaps)
|
|
||||||
redirections.TryAdd(path, file);
|
|
||||||
manipulations.UnionWith(Manipulations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsDefault { get; }
|
|
||||||
|
|
||||||
public static void WriteSubMod(JsonWriter j, JsonSerializer serializer, ISubMod mod, DirectoryInfo basePath, ModPriority? priority)
|
|
||||||
{
|
|
||||||
j.WriteStartObject();
|
|
||||||
j.WritePropertyName(nameof(Name));
|
|
||||||
j.WriteValue(mod.Name);
|
|
||||||
j.WritePropertyName(nameof(Description));
|
|
||||||
j.WriteValue(mod.Description);
|
|
||||||
if (priority != null)
|
|
||||||
{
|
|
||||||
j.WritePropertyName(nameof(IModGroup.Priority));
|
|
||||||
j.WriteValue(priority.Value.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
j.WritePropertyName(nameof(mod.Files));
|
|
||||||
j.WriteStartObject();
|
|
||||||
foreach (var (gamePath, file) in mod.Files)
|
|
||||||
{
|
|
||||||
if (file.ToRelPath(basePath, out var relPath))
|
|
||||||
{
|
|
||||||
j.WritePropertyName(gamePath.ToString());
|
|
||||||
j.WriteValue(relPath.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
j.WriteEndObject();
|
|
||||||
j.WritePropertyName(nameof(mod.FileSwaps));
|
|
||||||
j.WriteStartObject();
|
|
||||||
foreach (var (gamePath, file) in mod.FileSwaps)
|
|
||||||
{
|
|
||||||
j.WritePropertyName(gamePath.ToString());
|
|
||||||
j.WriteValue(file.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
j.WriteEndObject();
|
|
||||||
j.WritePropertyName(nameof(mod.Manipulations));
|
|
||||||
serializer.Serialize(j, mod.Manipulations);
|
|
||||||
j.WriteEndObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ using OtterGui;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
||||||
|
|
@ -34,44 +35,14 @@ public class ModSettings
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return everything required to resolve things for a single mod with given settings (which can be null, in which case the default is used.
|
// Return everything required to resolve things for a single mod with given settings (which can be null, in which case the default is used.
|
||||||
public static (Dictionary<Utf8GamePath, FullPath>, HashSet<MetaManipulation>) GetResolveData(Mod mod, ModSettings? settings)
|
public static AppliedModData GetResolveData(Mod mod, ModSettings? settings)
|
||||||
{
|
{
|
||||||
if (settings == null)
|
if (settings == null)
|
||||||
settings = DefaultSettings(mod);
|
settings = DefaultSettings(mod);
|
||||||
else
|
else
|
||||||
settings.Settings.FixSize(mod);
|
settings.Settings.FixSize(mod);
|
||||||
|
|
||||||
var dict = new Dictionary<Utf8GamePath, FullPath>();
|
return mod.GetData(settings);
|
||||||
var set = new HashSet<MetaManipulation>();
|
|
||||||
|
|
||||||
foreach (var (group, index) in mod.Groups.WithIndex().OrderByDescending(g => g.Value.Priority))
|
|
||||||
{
|
|
||||||
if (group.Type is GroupType.Single)
|
|
||||||
{
|
|
||||||
if (group.Count > 0)
|
|
||||||
AddOption(group[settings.Settings[index].AsIndex]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var (option, optionIdx) in group.WithIndex().OrderByDescending(o => group.OptionPriority(o.Index)))
|
|
||||||
{
|
|
||||||
if (settings.Settings[index].HasFlag(optionIdx))
|
|
||||||
AddOption(option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AddOption(mod.Default);
|
|
||||||
return (dict, set);
|
|
||||||
|
|
||||||
void AddOption(ISubMod option)
|
|
||||||
{
|
|
||||||
foreach (var (path, file) in option.Files.Concat(option.FileSwaps))
|
|
||||||
dict.TryAdd(path, file);
|
|
||||||
|
|
||||||
foreach (var manip in option.Manipulations)
|
|
||||||
set.Add(manip);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automatically react to changes in a mods available options.
|
// Automatically react to changes in a mods available options.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public sealed class MultiModGroup : IModGroup
|
||||||
public ModPriority OptionPriority(Index idx)
|
public ModPriority OptionPriority(Index idx)
|
||||||
=> PrioritizedOptions[idx].Priority;
|
=> PrioritizedOptions[idx].Priority;
|
||||||
|
|
||||||
public ISubMod this[Index idx]
|
public SubMod this[Index idx]
|
||||||
=> PrioritizedOptions[idx].Mod;
|
=> PrioritizedOptions[idx].Mod;
|
||||||
|
|
||||||
public bool IsOption
|
public bool IsOption
|
||||||
|
|
@ -36,7 +36,7 @@ public sealed class MultiModGroup : IModGroup
|
||||||
|
|
||||||
public readonly List<(SubMod Mod, ModPriority Priority)> PrioritizedOptions = [];
|
public readonly List<(SubMod Mod, ModPriority Priority)> PrioritizedOptions = [];
|
||||||
|
|
||||||
public IEnumerator<ISubMod> GetEnumerator()
|
public IEnumerator<SubMod> GetEnumerator()
|
||||||
=> PrioritizedOptions.Select(o => o.Mod).GetEnumerator();
|
=> PrioritizedOptions.Select(o => o.Mod).GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
|
@ -117,7 +117,7 @@ public sealed class MultiModGroup : IModGroup
|
||||||
foreach (var (option, index) in PrioritizedOptions.WithIndex().OrderByDescending(o => o.Value.Priority))
|
foreach (var (option, index) in PrioritizedOptions.WithIndex().OrderByDescending(o => o.Value.Priority))
|
||||||
{
|
{
|
||||||
if (setting.HasFlag(index))
|
if (setting.HasFlag(index))
|
||||||
((ISubMod)option.Mod).AddData(redirections, manipulations);
|
option.Mod.AddData(redirections, manipulations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public sealed class SingleModGroup : IModGroup
|
||||||
public ModPriority OptionPriority(Index _)
|
public ModPriority OptionPriority(Index _)
|
||||||
=> Priority;
|
=> Priority;
|
||||||
|
|
||||||
public ISubMod this[Index idx]
|
public SubMod this[Index idx]
|
||||||
=> OptionData[idx];
|
=> OptionData[idx];
|
||||||
|
|
||||||
public bool IsOption
|
public bool IsOption
|
||||||
|
|
@ -34,7 +34,7 @@ public sealed class SingleModGroup : IModGroup
|
||||||
public int Count
|
public int Count
|
||||||
=> OptionData.Count;
|
=> OptionData.Count;
|
||||||
|
|
||||||
public IEnumerator<ISubMod> GetEnumerator()
|
public IEnumerator<SubMod> GetEnumerator()
|
||||||
=> OptionData.GetEnumerator();
|
=> OptionData.GetEnumerator();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
|
|
@ -15,7 +16,7 @@ namespace Penumbra.Mods.Subclasses;
|
||||||
/// Nothing is checked for existence or validity when loading.
|
/// Nothing is checked for existence or validity when loading.
|
||||||
/// Objects are also not checked for uniqueness, the first appearance of a game path or meta path decides.
|
/// Objects are also not checked for uniqueness, the first appearance of a game path or meta path decides.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class SubMod : ISubMod
|
public sealed class SubMod
|
||||||
{
|
{
|
||||||
public string Name { get; set; } = "Default";
|
public string Name { get; set; } = "Default";
|
||||||
|
|
||||||
|
|
@ -31,6 +32,16 @@ public sealed class SubMod : ISubMod
|
||||||
public bool IsDefault
|
public bool IsDefault
|
||||||
=> GroupIdx < 0;
|
=> GroupIdx < 0;
|
||||||
|
|
||||||
|
public void AddData(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||||
|
{
|
||||||
|
foreach (var (path, file) in Files)
|
||||||
|
redirections.TryAdd(path, file);
|
||||||
|
|
||||||
|
foreach (var (path, file) in FileSwaps)
|
||||||
|
redirections.TryAdd(path, file);
|
||||||
|
manipulations.UnionWith(Manipulations);
|
||||||
|
}
|
||||||
|
|
||||||
public Dictionary<Utf8GamePath, FullPath> FileData = [];
|
public Dictionary<Utf8GamePath, FullPath> FileData = [];
|
||||||
public Dictionary<Utf8GamePath, FullPath> FileSwapData = [];
|
public Dictionary<Utf8GamePath, FullPath> FileSwapData = [];
|
||||||
public HashSet<MetaManipulation> ManipulationData = [];
|
public HashSet<MetaManipulation> ManipulationData = [];
|
||||||
|
|
@ -60,8 +71,8 @@ public sealed class SubMod : ISubMod
|
||||||
ManipulationData.Clear();
|
ManipulationData.Clear();
|
||||||
|
|
||||||
// Every option has a name, but priorities are only relevant for multi group options.
|
// Every option has a name, but priorities are only relevant for multi group options.
|
||||||
Name = json[nameof(ISubMod.Name)]?.ToObject<string>() ?? string.Empty;
|
Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty;
|
||||||
Description = json[nameof(ISubMod.Description)]?.ToObject<string>() ?? string.Empty;
|
Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty;
|
||||||
priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default;
|
priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default;
|
||||||
|
|
||||||
var files = (JObject?)json[nameof(Files)];
|
var files = (JObject?)json[nameof(Files)];
|
||||||
|
|
@ -104,4 +115,43 @@ public sealed class SubMod : ISubMod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteSubMod(JsonWriter j, JsonSerializer serializer, SubMod mod, DirectoryInfo basePath, ModPriority? priority)
|
||||||
|
{
|
||||||
|
j.WriteStartObject();
|
||||||
|
j.WritePropertyName(nameof(Name));
|
||||||
|
j.WriteValue(mod.Name);
|
||||||
|
j.WritePropertyName(nameof(Description));
|
||||||
|
j.WriteValue(mod.Description);
|
||||||
|
if (priority != null)
|
||||||
|
{
|
||||||
|
j.WritePropertyName(nameof(IModGroup.Priority));
|
||||||
|
j.WriteValue(priority.Value.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
j.WritePropertyName(nameof(mod.Files));
|
||||||
|
j.WriteStartObject();
|
||||||
|
foreach (var (gamePath, file) in mod.Files)
|
||||||
|
{
|
||||||
|
if (file.ToRelPath(basePath, out var relPath))
|
||||||
|
{
|
||||||
|
j.WritePropertyName(gamePath.ToString());
|
||||||
|
j.WriteValue(relPath.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j.WriteEndObject();
|
||||||
|
j.WritePropertyName(nameof(mod.FileSwaps));
|
||||||
|
j.WriteStartObject();
|
||||||
|
foreach (var (gamePath, file) in mod.FileSwaps)
|
||||||
|
{
|
||||||
|
j.WritePropertyName(gamePath.ToString());
|
||||||
|
j.WriteValue(file.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
j.WriteEndObject();
|
||||||
|
j.WritePropertyName(nameof(mod.Manipulations));
|
||||||
|
serializer.Serialize(j, mod.Manipulations);
|
||||||
|
j.WriteEndObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,9 @@ public class TemporaryMod : IMod
|
||||||
dict.TryAdd(gamePath, file);
|
dict.TryAdd(gamePath, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AppliedModData(dict, Default.Manipulations);
|
return new AppliedModData(dict, Default.ManipulationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ISubMod IMod.Default
|
|
||||||
=> Default;
|
|
||||||
|
|
||||||
public IReadOnlyList<IModGroup> Groups
|
public IReadOnlyList<IModGroup> Groups
|
||||||
=> Array.Empty<IModGroup>();
|
=> Array.Empty<IModGroup>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ public partial class ModEditWindow
|
||||||
ImGuiUtil.RightAlign(rightText);
|
ImGuiUtil.RightAlign(rightText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrintGamePath(int i, int j, FileRegistry registry, ISubMod subMod, Utf8GamePath gamePath)
|
private void PrintGamePath(int i, int j, FileRegistry registry, SubMod subMod, Utf8GamePath gamePath)
|
||||||
{
|
{
|
||||||
using var id = ImRaii.PushId(j);
|
using var id = ImRaii.PushId(j);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -228,7 +228,7 @@ public partial class ModEditWindow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrintNewGamePath(int i, FileRegistry registry, ISubMod subMod)
|
private void PrintNewGamePath(int i, FileRegistry registry, SubMod subMod)
|
||||||
{
|
{
|
||||||
var tmp = _fileIdx == i && _pathIdx == -1 ? _gamePathEdit : string.Empty;
|
var tmp = _fileIdx == i && _pathIdx == -1 ? _gamePathEdit : string.Empty;
|
||||||
var pos = ImGui.GetCursorPosX() - ImGui.GetFrameHeight();
|
var pos = ImGui.GetCursorPosX() - ImGui.GetFrameHeight();
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ public partial class ModEditWindow
|
||||||
return fileRegistry;
|
return fileRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (DirectoryInfo, int) GetPreferredPath(Mod mod, ISubMod subMod, bool replaceNonAscii)
|
private static (DirectoryInfo, int) GetPreferredPath(Mod mod, SubMod subMod, bool replaceNonAscii)
|
||||||
{
|
{
|
||||||
var path = mod.ModPath;
|
var path = mod.ModPath;
|
||||||
var subDirs = 0;
|
var subDirs = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue