Rework options, pre-submod types.

This commit is contained in:
Ottermandias 2024-04-23 17:41:55 +02:00
parent 792a04337f
commit 07afbfb229
25 changed files with 620 additions and 300 deletions

View file

@ -1,3 +1,4 @@
using System;
using OtterGui;
using OtterGui.Compression;
using Penumbra.Mods.Subclasses;
@ -72,12 +73,18 @@ public class ModEditor(
if (groupIdx >= 0)
{
Group = Mod.Groups[groupIdx];
if (optionIdx >= 0 && optionIdx < Group.Count)
switch(Group)
{
Option = Group[optionIdx];
GroupIdx = groupIdx;
OptionIdx = optionIdx;
return;
case SingleModGroup single when optionIdx >= 0 && optionIdx < single.OptionData.Count:
Option = single.OptionData[optionIdx];
GroupIdx = groupIdx;
OptionIdx = optionIdx;
return;
case MultiModGroup multi when optionIdx >= 0 && optionIdx < multi.PrioritizedOptions.Count:
Option = multi.PrioritizedOptions[optionIdx].Mod;
GroupIdx = groupIdx;
OptionIdx = optionIdx;
return;
}
}
}
@ -109,8 +116,17 @@ public class ModEditor(
action(mod.Default, -1, 0);
foreach (var (group, groupIdx) in mod.Groups.WithIndex())
{
for (var optionIdx = 0; optionIdx < group.Count; ++optionIdx)
action(group[optionIdx], groupIdx, optionIdx);
switch (group)
{
case SingleModGroup single:
for (var optionIdx = 0; optionIdx < single.OptionData.Count; ++optionIdx)
action(single.OptionData[optionIdx], groupIdx, optionIdx);
break;
case MultiModGroup multi:
for (var optionIdx = 0; optionIdx < multi.PrioritizedOptions.Count; ++optionIdx)
action(multi.PrioritizedOptions[optionIdx].Mod, groupIdx, optionIdx);
break;
}
}
}

View file

@ -24,7 +24,8 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
num += dict.TryAdd(path.Item2, file.File) ? 0 : 1;
}
modManager.OptionEditor.OptionSetFiles(mod, option.GroupIdx, option.OptionIdx, dict);
var (groupIdx, optionIdx) = option.GetIndices();
modManager.OptionEditor.OptionSetFiles(mod, groupIdx, optionIdx, dict);
files.UpdatePaths(mod, option);
Changes = false;
return num;

View file

@ -1,5 +1,6 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Utility;
using ImGuizmoNET;
using OtterGui;
using OtterGui.Classes;
using Penumbra.Api.Enums;
@ -104,9 +105,16 @@ public class ModMerger : IDisposable
((List<string>)Warnings).Add(
$"The merged group {group.Name} already existed, but has a different type {group.Type} than the original group of type {originalGroup.Type}.");
foreach (var originalOption in originalGroup)
var optionEnumerator = group switch
{
var (option, optionCreated) = _editor.FindOrAddOption(MergeToMod!, groupIdx, originalOption.Name);
SingleModGroup single => single.OptionData,
MultiModGroup multi => multi.PrioritizedOptions.Select(o => o.Mod),
_ => [],
};
foreach (var originalOption in optionEnumerator)
{
var (option, _, optionCreated) = _editor.FindOrAddOption(MergeToMod!, groupIdx, originalOption.Name);
if (optionCreated)
{
_createdOptions.Add(option);
@ -138,7 +146,7 @@ public class ModMerger : IDisposable
var (group, groupIdx, groupCreated) = _editor.FindOrAddModGroup(MergeToMod!, GroupType.Multi, groupName, SaveType.None);
if (groupCreated)
_createdGroups.Add(groupIdx);
var (option, optionCreated) = _editor.FindOrAddOption(MergeToMod!, groupIdx, optionName, SaveType.None);
var (option, _, optionCreated) = _editor.FindOrAddOption(MergeToMod!, groupIdx, optionName, SaveType.None);
if (optionCreated)
_createdOptions.Add(option);
var dir = ModCreator.NewOptionDirectory(MergeToMod!.ModPath, groupName, _config.ReplaceNonAsciiOnImport);
@ -184,9 +192,10 @@ public class ModMerger : IDisposable
}
}
_editor.OptionSetFiles(MergeToMod!, option.GroupIdx, option.OptionIdx, redirections, SaveType.None);
_editor.OptionSetFileSwaps(MergeToMod!, option.GroupIdx, option.OptionIdx, swaps, SaveType.None);
_editor.OptionSetManipulations(MergeToMod!, option.GroupIdx, option.OptionIdx, manips, SaveType.ImmediateSync);
var (groupIdx, optionIdx) = option.GetIndices();
_editor.OptionSetFiles(MergeToMod!, groupIdx, optionIdx, redirections, SaveType.None);
_editor.OptionSetFileSwaps(MergeToMod!, groupIdx, optionIdx, swaps, SaveType.None);
_editor.OptionSetManipulations(MergeToMod!, groupIdx, optionIdx, manips, SaveType.ImmediateSync);
return;
bool GetFullPath(FullPath input, out FullPath ret)
@ -251,7 +260,7 @@ public class ModMerger : IDisposable
Mod? result = null;
try
{
dir = _creator.CreateEmptyMod(_mods.BasePath, modName, $"Split off from {mods[0].ParentMod.Name}.");
dir = _creator.CreateEmptyMod(_mods.BasePath, modName, $"Split off from {mods[0].Mod.Name}.");
if (dir == null)
throw new Exception($"Could not split off mods, unable to create new mod with name {modName}.");
@ -268,7 +277,6 @@ public class ModMerger : IDisposable
{
foreach (var originalOption in mods)
{
var originalGroup = originalOption.ParentMod.Groups[originalOption.GroupIdx];
if (originalOption.IsDefault)
{
var files = CopySubModFiles(mods[0], dir);
@ -278,13 +286,14 @@ public class ModMerger : IDisposable
}
else
{
var originalGroup = originalOption.Group;
var (group, groupIdx, _) = _editor.FindOrAddModGroup(result, originalGroup.Type, originalGroup.Name);
var (option, _) = _editor.FindOrAddOption(result, groupIdx, originalOption.Name);
var (option, optionIdx, _) = _editor.FindOrAddOption(result, groupIdx, originalOption.Name);
var folder = Path.Combine(dir.FullName, group.Name, option.Name);
var files = CopySubModFiles(originalOption, new DirectoryInfo(folder));
_editor.OptionSetFiles(result, groupIdx, option.OptionIdx, files);
_editor.OptionSetFileSwaps(result, groupIdx, option.OptionIdx, originalOption.FileSwapData);
_editor.OptionSetManipulations(result, groupIdx, option.OptionIdx, originalOption.ManipulationData);
_editor.OptionSetFiles(result, groupIdx, optionIdx, files);
_editor.OptionSetFileSwaps(result, groupIdx, optionIdx, originalOption.FileSwapData);
_editor.OptionSetManipulations(result, groupIdx, optionIdx, originalOption.ManipulationData);
}
}
}
@ -309,7 +318,7 @@ public class ModMerger : IDisposable
private static Dictionary<Utf8GamePath, FullPath> CopySubModFiles(SubMod option, DirectoryInfo newMod)
{
var ret = new Dictionary<Utf8GamePath, FullPath>(option.FileData.Count);
var parentPath = ((Mod)option.ParentMod).ModPath.FullName;
var parentPath = ((Mod)option.Mod).ModPath.FullName;
foreach (var (path, file) in option.FileData)
{
var target = Path.GetRelativePath(parentPath, file.FullName);
@ -339,7 +348,8 @@ public class ModMerger : IDisposable
{
foreach (var option in _createdOptions)
{
_editor.DeleteOption(MergeToMod!, option.GroupIdx, option.OptionIdx);
var (groupIdx, optionIdx) = option.GetIndices();
_editor.DeleteOption(MergeToMod!, groupIdx, optionIdx);
Penumbra.Log.Verbose($"[Merger] Removed option {option.FullName}.");
}

View file

@ -167,28 +167,27 @@ public class ModNormalizer(ModManager _modManager, Configuration _config)
// Normalize all other options.
foreach (var (group, groupIdx) in Mod.Groups.WithIndex())
{
_redirections[groupIdx + 1].EnsureCapacity(group.Count);
for (var i = _redirections[groupIdx + 1].Count; i < group.Count; ++i)
_redirections[groupIdx + 1].Add([]);
var groupDir = ModCreator.CreateModFolder(directory, group.Name, _config.ReplaceNonAsciiOnImport, true);
foreach (var option in group.OfType<SubMod>())
switch (group)
{
var optionDir = ModCreator.CreateModFolder(groupDir, option.Name, _config.ReplaceNonAsciiOnImport, true);
case SingleModGroup single:
_redirections[groupIdx + 1].EnsureCapacity(single.OptionData.Count);
for (var i = _redirections[groupIdx + 1].Count; i < single.OptionData.Count; ++i)
_redirections[groupIdx + 1].Add([]);
newDict = _redirections[groupIdx + 1][option.OptionIdx];
newDict.Clear();
newDict.EnsureCapacity(option.FileData.Count);
foreach (var (gamePath, fullPath) in option.FileData)
{
var relPath = new Utf8RelPath(gamePath).ToString();
var newFullPath = Path.Combine(optionDir.FullName, relPath);
var redirectPath = new FullPath(Path.Combine(Mod.ModPath.FullName, groupDir.Name, optionDir.Name, relPath));
Directory.CreateDirectory(Path.GetDirectoryName(newFullPath)!);
File.Copy(fullPath.FullName, newFullPath, true);
newDict.Add(gamePath, redirectPath);
++Step;
}
foreach (var (option, optionIdx) in single.OptionData.WithIndex())
HandleSubMod(groupDir, option, _redirections[groupIdx + 1][optionIdx]);
break;
case MultiModGroup multi:
_redirections[groupIdx + 1].EnsureCapacity(multi.PrioritizedOptions.Count);
for (var i = _redirections[groupIdx + 1].Count; i < multi.PrioritizedOptions.Count; ++i)
_redirections[groupIdx + 1].Add([]);
foreach (var ((option, _), optionIdx) in multi.PrioritizedOptions.WithIndex())
HandleSubMod(groupDir, option, _redirections[groupIdx + 1][optionIdx]);
break;
}
}
@ -200,6 +199,24 @@ public class ModNormalizer(ModManager _modManager, Configuration _config)
}
return false;
void HandleSubMod(DirectoryInfo groupDir, SubMod option, Dictionary<Utf8GamePath, FullPath> newDict)
{
var optionDir = ModCreator.CreateModFolder(groupDir, option.Name, _config.ReplaceNonAsciiOnImport, true);
newDict.Clear();
newDict.EnsureCapacity(option.FileData.Count);
foreach (var (gamePath, fullPath) in option.FileData)
{
var relPath = new Utf8RelPath(gamePath).ToString();
var newFullPath = Path.Combine(optionDir.FullName, relPath);
var redirectPath = new FullPath(Path.Combine(Mod.ModPath.FullName, groupDir.Name, optionDir.Name, relPath));
Directory.CreateDirectory(Path.GetDirectoryName(newFullPath)!);
File.Copy(fullPath.FullName, newFullPath, true);
newDict.Add(gamePath, redirectPath);
++Step;
}
}
}
private bool MoveOldFiles()
@ -274,9 +291,20 @@ public class ModNormalizer(ModManager _modManager, Configuration _config)
private void ApplyRedirections()
{
foreach (var option in Mod.AllSubMods)
_modManager.OptionEditor.OptionSetFiles(Mod, option.GroupIdx, option.OptionIdx,
_redirections[option.GroupIdx + 1][option.OptionIdx]);
foreach (var (group, groupIdx) in Mod.Groups.WithIndex())
{
switch (group)
{
case SingleModGroup single:
foreach (var (_, optionIdx) in single.OptionData.WithIndex())
_modManager.OptionEditor.OptionSetFiles(Mod, groupIdx, optionIdx, _redirections[groupIdx + 1][optionIdx]);
break;
case MultiModGroup multi:
foreach (var (_, optionIdx) in multi.PrioritizedOptions.WithIndex())
_modManager.OptionEditor.OptionSetFiles(Mod, groupIdx, optionIdx, _redirections[groupIdx + 1][optionIdx]);
break;
}
}
++Step;
}