mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 10:17:22 +01:00
Reorder stuff.
This commit is contained in:
parent
6b1743b776
commit
514121d8c1
58 changed files with 416 additions and 539 deletions
|
|
@ -8,8 +8,9 @@ using Penumbra.Communication;
|
|||
using Penumbra.Interop.PathResolving;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Api.Api;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using Penumbra.Collections.Manager;
|
|||
using Penumbra.GameData.Actors;
|
||||
using Penumbra.GameData.Interop;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Api.Api;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using Penumbra.Services;
|
|||
using Penumbra.String.Classes;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Penumbra.Interop.ResourceLoading;
|
|||
using Penumbra.Meta;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using OtterGui;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Collections.Manager;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using Penumbra.Communication;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Collections.Manager;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Util;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using Newtonsoft.Json.Linq;
|
|||
using Penumbra.Services;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Penumbra.Api.Api;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.Communication;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ using OtterGui;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Util;
|
||||
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ using Penumbra.Interop.Services;
|
|||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Services;
|
||||
using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using OtterGui.Classes;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using OtterGui;
|
||||
using OtterGui.Compression;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.SubMods;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using OtterGui;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using OtterGui.Classes;
|
|||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Communication;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.ModsTab;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ using Dalamud.Interface.Internal.Notifications;
|
|||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Tasks;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Groups;
|
||||
|
||||
public interface ITexToolsGroup
|
||||
{
|
||||
|
|
@ -16,22 +16,22 @@ public interface IModGroup
|
|||
{
|
||||
public const int MaxMultiOptions = 63;
|
||||
|
||||
public Mod Mod { get; }
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public GroupType Type { get; }
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
public Mod Mod { get; }
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public GroupType Type { get; }
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
|
||||
public FullPath? FindBestMatch(Utf8GamePath gamePath);
|
||||
public int AddOption(Mod mod, string name, string description = "");
|
||||
public int AddOption(Mod mod, string name, string description = "");
|
||||
|
||||
public IReadOnlyList<IModOption> Options { get; }
|
||||
public IReadOnlyList<IModOption> Options { get; }
|
||||
public IReadOnlyList<IModDataContainer> DataContainers { get; }
|
||||
public bool IsOption { get; }
|
||||
public bool IsOption { get; }
|
||||
|
||||
public IModGroup Convert(GroupType type);
|
||||
public bool MoveOption(int optionIdxFrom, int optionIdxTo);
|
||||
public bool MoveOption(int optionIdxFrom, int optionIdxTo);
|
||||
|
||||
public int GetIndex();
|
||||
|
||||
|
|
@ -88,67 +88,15 @@ public interface IModGroup
|
|||
public static (int Redirections, int Swaps, int Manips) GetCountsBase(IModGroup group)
|
||||
{
|
||||
var redirectionCount = 0;
|
||||
var swapCount = 0;
|
||||
var manipCount = 0;
|
||||
var swapCount = 0;
|
||||
var manipCount = 0;
|
||||
foreach (var option in group.DataContainers)
|
||||
{
|
||||
redirectionCount += option.Files.Count;
|
||||
swapCount += option.FileSwaps.Count;
|
||||
manipCount += option.Manipulations.Count;
|
||||
swapCount += option.FileSwaps.Count;
|
||||
manipCount += option.Manipulations.Count;
|
||||
}
|
||||
|
||||
return (redirectionCount, swapCount, manipCount);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct ModSaveGroup : ISavable
|
||||
{
|
||||
private readonly DirectoryInfo _basePath;
|
||||
private readonly IModGroup? _group;
|
||||
private readonly int _groupIdx;
|
||||
private readonly DefaultSubMod? _defaultMod;
|
||||
private readonly bool _onlyAscii;
|
||||
|
||||
public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii)
|
||||
{
|
||||
_basePath = mod.ModPath;
|
||||
_groupIdx = groupIdx;
|
||||
if (_groupIdx < 0)
|
||||
_defaultMod = mod.Default;
|
||||
else
|
||||
_group = mod.Groups[_groupIdx];
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public ModSaveGroup(DirectoryInfo basePath, IModGroup group, int groupIdx, bool onlyAscii)
|
||||
{
|
||||
_basePath = basePath;
|
||||
_group = group;
|
||||
_groupIdx = groupIdx;
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public ModSaveGroup(DirectoryInfo basePath, DefaultSubMod @default, bool onlyAscii)
|
||||
{
|
||||
_basePath = basePath;
|
||||
_groupIdx = -1;
|
||||
_defaultMod = @default;
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.OptionGroupFile(_basePath.FullName, _groupIdx, _group?.Name ?? string.Empty, _onlyAscii);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
using var j = new JsonTextWriter(writer);
|
||||
j.Formatting = Formatting.Indented;
|
||||
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
|
||||
j.WriteStartObject();
|
||||
if (_groupIdx >= 0)
|
||||
_group!.WriteJson(j, serializer);
|
||||
else
|
||||
IModDataContainer.WriteModData(j, serializer, _defaultMod!, _basePath);
|
||||
j.WriteEndObject();
|
||||
}
|
||||
}
|
||||
57
Penumbra/Mods/Groups/ModSaveGroup.cs
Normal file
57
Penumbra/Mods/Groups/ModSaveGroup.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using Newtonsoft.Json;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods.Groups;
|
||||
|
||||
public readonly struct ModSaveGroup : ISavable
|
||||
{
|
||||
private readonly DirectoryInfo _basePath;
|
||||
private readonly IModGroup? _group;
|
||||
private readonly int _groupIdx;
|
||||
private readonly DefaultSubMod? _defaultMod;
|
||||
private readonly bool _onlyAscii;
|
||||
|
||||
public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii)
|
||||
{
|
||||
_basePath = mod.ModPath;
|
||||
_groupIdx = groupIdx;
|
||||
if (_groupIdx < 0)
|
||||
_defaultMod = mod.Default;
|
||||
else
|
||||
_group = mod.Groups[_groupIdx];
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public ModSaveGroup(DirectoryInfo basePath, IModGroup group, int groupIdx, bool onlyAscii)
|
||||
{
|
||||
_basePath = basePath;
|
||||
_group = group;
|
||||
_groupIdx = groupIdx;
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public ModSaveGroup(DirectoryInfo basePath, DefaultSubMod @default, bool onlyAscii)
|
||||
{
|
||||
_basePath = basePath;
|
||||
_groupIdx = -1;
|
||||
_defaultMod = @default;
|
||||
_onlyAscii = onlyAscii;
|
||||
}
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.OptionGroupFile(_basePath.FullName, _groupIdx, _group?.Name ?? string.Empty, _onlyAscii);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
using var j = new JsonTextWriter(writer);
|
||||
j.Formatting = Formatting.Indented;
|
||||
var serializer = new JsonSerializer { Formatting = Formatting.Indented };
|
||||
j.WriteStartObject();
|
||||
if (_groupIdx >= 0)
|
||||
_group!.WriteJson(j, serializer);
|
||||
else
|
||||
IModDataContainer.WriteModData(j, serializer, _defaultMod!, _basePath);
|
||||
j.WriteEndObject();
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,11 @@ using OtterGui.Classes;
|
|||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Groups;
|
||||
|
||||
/// <summary> Groups that allow all available options to be selected at once. </summary>
|
||||
public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
||||
|
|
@ -16,11 +18,11 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
public GroupType Type
|
||||
=> GroupType.Multi;
|
||||
|
||||
public Mod Mod { get; set; } = mod;
|
||||
public string Name { get; set; } = "Group";
|
||||
public string Description { get; set; } = "A non-exclusive group of settings.";
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
public Mod Mod { get; set; } = mod;
|
||||
public string Name { get; set; } = "Group";
|
||||
public string Description { get; set; } = "A non-exclusive group of settings.";
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
public readonly List<MultiSubMod> OptionData = [];
|
||||
|
||||
public IReadOnlyList<IModOption> Options
|
||||
|
|
@ -45,7 +47,7 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
|
||||
var subMod = new MultiSubMod(mod, this)
|
||||
{
|
||||
Name = name,
|
||||
Name = name,
|
||||
Description = description,
|
||||
};
|
||||
OptionData.Add(subMod);
|
||||
|
|
@ -56,9 +58,9 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
{
|
||||
var ret = new MultiModGroup(mod)
|
||||
{
|
||||
Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty,
|
||||
Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty,
|
||||
Priority = json[nameof(Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default,
|
||||
Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty,
|
||||
Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty,
|
||||
Priority = json[nameof(Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default,
|
||||
DefaultSettings = json[nameof(DefaultSettings)]?.ToObject<Setting>() ?? Setting.Zero,
|
||||
};
|
||||
if (ret.Name.Length == 0)
|
||||
|
|
@ -93,9 +95,9 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
case GroupType.Single:
|
||||
var single = new SingleModGroup(Mod)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
DefaultSettings = DefaultSettings.TurnMulti(OptionData.Count),
|
||||
};
|
||||
single.OptionData.AddRange(OptionData.Select(o => o.ConvertToSingle(Mod, single)));
|
||||
|
|
@ -152,7 +154,7 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
=> IModGroup.GetCountsBase(this);
|
||||
|
||||
public Setting FixSetting(Setting setting)
|
||||
=> new(setting.Value & ((1ul << OptionData.Count) - 1));
|
||||
=> new(setting.Value & (1ul << OptionData.Count) - 1);
|
||||
|
||||
/// <summary> Create a group without a mod only for saving it in the creator. </summary>
|
||||
internal static MultiModGroup CreateForSaving(string name)
|
||||
|
|
@ -4,9 +4,11 @@ using OtterGui;
|
|||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Groups;
|
||||
|
||||
/// <summary> Groups that allow only one of their available options to be selected. </summary>
|
||||
public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
||||
|
|
@ -14,11 +16,11 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
public GroupType Type
|
||||
=> GroupType.Single;
|
||||
|
||||
public Mod Mod { get; set; } = mod;
|
||||
public string Name { get; set; } = "Option";
|
||||
public string Description { get; set; } = "A mutually exclusive group of settings.";
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
public Mod Mod { get; set; } = mod;
|
||||
public string Name { get; set; } = "Option";
|
||||
public string Description { get; set; } = "A mutually exclusive group of settings.";
|
||||
public ModPriority Priority { get; set; }
|
||||
public Setting DefaultSettings { get; set; }
|
||||
|
||||
public readonly List<SingleSubMod> OptionData = [];
|
||||
|
||||
|
|
@ -34,7 +36,7 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
{
|
||||
var subMod = new SingleSubMod(mod, this)
|
||||
{
|
||||
Name = name,
|
||||
Name = name,
|
||||
Description = description,
|
||||
};
|
||||
OptionData.Add(subMod);
|
||||
|
|
@ -55,9 +57,9 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
var options = json["Options"];
|
||||
var ret = new SingleModGroup(mod)
|
||||
{
|
||||
Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty,
|
||||
Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty,
|
||||
Priority = json[nameof(Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default,
|
||||
Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty,
|
||||
Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty,
|
||||
Priority = json[nameof(Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default,
|
||||
DefaultSettings = json[nameof(DefaultSettings)]?.ToObject<Setting>() ?? Setting.Zero,
|
||||
};
|
||||
if (ret.Name.Length == 0)
|
||||
|
|
@ -82,9 +84,9 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup
|
|||
case GroupType.Multi:
|
||||
var multi = new MultiModGroup(Mod)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
DefaultSettings = Setting.Multi((int)DefaultSettings.Value),
|
||||
};
|
||||
multi.OptionData.AddRange(OptionData.Select((o, i) => o.ConvertToMulti(Mod, multi, new ModPriority(i))));
|
||||
|
|
@ -7,7 +7,7 @@ using Penumbra.String.Classes;
|
|||
using Penumbra.Meta;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.Mods.ItemSwap;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ using Penumbra.Communication;
|
|||
using Penumbra.GameData.Data;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Services;
|
||||
|
||||
namespace Penumbra.Mods.Manager;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ using OtterGui.Classes;
|
|||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.Util;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
using OtterGui;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.Collections.Cache;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ using Penumbra.GameData.Data;
|
|||
using Penumbra.Import;
|
||||
using Penumbra.Import.Structs;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,29 +5,25 @@ using Penumbra.Services;
|
|||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public readonly struct ModLocalData : ISavable
|
||||
public readonly struct ModLocalData(Mod mod) : ISavable
|
||||
{
|
||||
public const int FileVersion = 3;
|
||||
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModLocalData(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.LocalDataFile(_mod);
|
||||
=> fileNames.LocalDataFile(mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(FileVersion), JToken.FromObject(FileVersion) },
|
||||
{ nameof(Mod.ImportDate), JToken.FromObject(_mod.ImportDate) },
|
||||
{ nameof(Mod.LocalTags), JToken.FromObject(_mod.LocalTags) },
|
||||
{ nameof(Mod.Note), JToken.FromObject(_mod.Note) },
|
||||
{ nameof(Mod.Favorite), JToken.FromObject(_mod.Favorite) },
|
||||
{ nameof(Mod.ImportDate), JToken.FromObject(mod.ImportDate) },
|
||||
{ nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) },
|
||||
{ nameof(Mod.Note), JToken.FromObject(mod.Note) },
|
||||
{ nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
using var jWriter = new JsonTextWriter(writer);
|
||||
jWriter.Formatting = Formatting.Indented;
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,31 +4,27 @@ using Penumbra.Services;
|
|||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public readonly struct ModMeta : ISavable
|
||||
public readonly struct ModMeta(Mod mod) : ISavable
|
||||
{
|
||||
public const uint FileVersion = 3;
|
||||
|
||||
private readonly Mod _mod;
|
||||
|
||||
public ModMeta(Mod mod)
|
||||
=> _mod = mod;
|
||||
|
||||
public string ToFilename(FilenameService fileNames)
|
||||
=> fileNames.ModMetaPath(_mod);
|
||||
=> fileNames.ModMetaPath(mod);
|
||||
|
||||
public void Save(StreamWriter writer)
|
||||
{
|
||||
var jObject = new JObject
|
||||
{
|
||||
{ nameof(FileVersion), JToken.FromObject(FileVersion) },
|
||||
{ nameof(Mod.Name), JToken.FromObject(_mod.Name) },
|
||||
{ nameof(Mod.Author), JToken.FromObject(_mod.Author) },
|
||||
{ nameof(Mod.Description), JToken.FromObject(_mod.Description) },
|
||||
{ nameof(Mod.Version), JToken.FromObject(_mod.Version) },
|
||||
{ nameof(Mod.Website), JToken.FromObject(_mod.Website) },
|
||||
{ nameof(Mod.ModTags), JToken.FromObject(_mod.ModTags) },
|
||||
{ nameof(Mod.Name), JToken.FromObject(mod.Name) },
|
||||
{ nameof(Mod.Author), JToken.FromObject(mod.Author) },
|
||||
{ nameof(Mod.Description), JToken.FromObject(mod.Description) },
|
||||
{ nameof(Mod.Version), JToken.FromObject(mod.Version) },
|
||||
{ nameof(Mod.Website), JToken.FromObject(mod.Website) },
|
||||
{ nameof(Mod.ModTags), JToken.FromObject(mod.ModTags) },
|
||||
};
|
||||
using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented };
|
||||
using var jWriter = new JsonTextWriter(writer);
|
||||
jWriter.Formatting = Formatting.Indented;
|
||||
jObject.WriteTo(jWriter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Settings;
|
||||
|
||||
[JsonConverter(typeof(Converter))]
|
||||
public readonly record struct ModPriority(int Value) :
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Settings;
|
||||
|
||||
/// <summary> Contains the settings for a given mod. </summary>
|
||||
public class ModSettings
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using Newtonsoft.Json;
|
||||
using OtterGui;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Settings;
|
||||
|
||||
[JsonConverter(typeof(Converter))]
|
||||
public readonly record struct Setting(ulong Value)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.Settings;
|
||||
|
||||
public class SettingList : List<Setting>
|
||||
{
|
||||
30
Penumbra/Mods/SubMods/DefaultSubMod.cs
Normal file
30
Penumbra/Mods/SubMods/DefaultSubMod.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public class DefaultSubMod(IMod mod) : IModDataContainer
|
||||
{
|
||||
public const string FullName = "Default Option";
|
||||
|
||||
internal readonly IMod Mod = mod;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup? IModDataContainer.Group
|
||||
=> null;
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (-1, 0);
|
||||
}
|
||||
|
|
@ -2,18 +2,19 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public interface IModDataContainer
|
||||
{
|
||||
public IMod Mod { get; }
|
||||
public IMod Mod { get; }
|
||||
public IModGroup? Group { get; }
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; }
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; }
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; }
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; }
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; }
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; }
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
{
|
||||
|
|
@ -28,24 +29,24 @@ public interface IModDataContainer
|
|||
public string GetName()
|
||||
=> this switch
|
||||
{
|
||||
IModOption o => o.FullName,
|
||||
IModOption o => o.FullName,
|
||||
DefaultSubMod => DefaultSubMod.FullName,
|
||||
_ => $"Container {GetDataIndices().DataIndex + 1}",
|
||||
_ => $"Container {GetDataIndices().DataIndex + 1}",
|
||||
};
|
||||
|
||||
public string GetFullName()
|
||||
=> this switch
|
||||
{
|
||||
IModOption o => o.FullName,
|
||||
DefaultSubMod => DefaultSubMod.FullName,
|
||||
IModOption o => o.FullName,
|
||||
DefaultSubMod => DefaultSubMod.FullName,
|
||||
_ when Group != null => $"{Group.Name}: Container {GetDataIndices().DataIndex + 1}",
|
||||
_ => $"Container {GetDataIndices().DataIndex + 1}",
|
||||
_ => $"Container {GetDataIndices().DataIndex + 1}",
|
||||
};
|
||||
|
||||
public static void Clone(IModDataContainer from, IModDataContainer to)
|
||||
{
|
||||
to.Files = new Dictionary<Utf8GamePath, FullPath>(from.Files);
|
||||
to.FileSwaps = new Dictionary<Utf8GamePath, FullPath>(from.FileSwaps);
|
||||
to.Files = new Dictionary<Utf8GamePath, FullPath>(from.Files);
|
||||
to.FileSwaps = new Dictionary<Utf8GamePath, FullPath>(from.FileSwaps);
|
||||
to.Manipulations = [.. from.Manipulations];
|
||||
}
|
||||
|
||||
|
|
@ -126,3 +127,5 @@ public interface IModDataContainer
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IModDataOption : IModOption, IModDataContainer;
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public interface IModOption
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string FullName { get; }
|
||||
public string Name { get; set; }
|
||||
public string FullName { get; }
|
||||
public string Description { get; set; }
|
||||
|
||||
public static void Load(JToken json, IModOption option)
|
||||
{
|
||||
option.Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty;
|
||||
option.Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty;
|
||||
option.Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty;
|
||||
}
|
||||
|
||||
92
Penumbra/Mods/SubMods/MultiSubMod.cs
Normal file
92
Penumbra/Mods/SubMods/MultiSubMod.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public class MultiSubMod(Mod mod, MultiModGroup group) : IModDataOption
|
||||
{
|
||||
internal readonly Mod Mod = mod;
|
||||
internal readonly MultiModGroup Group = group;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
|
||||
public string FullName
|
||||
=> $"{Group.Name}: {Name}";
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public ModPriority Priority { get; set; } = ModPriority.Default;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup IModDataContainer.Group
|
||||
=> Group;
|
||||
|
||||
|
||||
public MultiSubMod(Mod mod, MultiModGroup group, JToken json)
|
||||
: this(mod, group)
|
||||
{
|
||||
IModOption.Load(json, this);
|
||||
IModDataContainer.Load(json, this, mod.ModPath);
|
||||
Priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default;
|
||||
}
|
||||
|
||||
public MultiSubMod Clone(Mod mod, MultiModGroup group)
|
||||
{
|
||||
var ret = new MultiSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SingleSubMod ConvertToSingle(Mod mod, SingleModGroup group)
|
||||
{
|
||||
var ret = new SingleSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public static MultiSubMod CreateForSaving(string name, string description, ModPriority priority)
|
||||
=> new(null!, null!)
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
Priority = priority,
|
||||
};
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
public (int GroupIndex, int OptionIndex) GetOptionIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
private int GetDataIndex()
|
||||
{
|
||||
var dataIndex = Group.DataContainers.IndexOf(this);
|
||||
if (dataIndex < 0)
|
||||
throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
|
||||
return dataIndex;
|
||||
}
|
||||
}
|
||||
82
Penumbra/Mods/SubMods/SingleSubMod.cs
Normal file
82
Penumbra/Mods/SubMods/SingleSubMod.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.SubMods;
|
||||
|
||||
public class SingleSubMod(Mod mod, SingleModGroup group) : IModDataOption
|
||||
{
|
||||
internal readonly Mod Mod = mod;
|
||||
internal readonly SingleModGroup Group = group;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
|
||||
public string FullName
|
||||
=> $"{Group.Name}: {Name}";
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup IModDataContainer.Group
|
||||
=> Group;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
public SingleSubMod(Mod mod, SingleModGroup group, JToken json)
|
||||
: this(mod, group)
|
||||
{
|
||||
IModOption.Load(json, this);
|
||||
IModDataContainer.Load(json, this, mod.ModPath);
|
||||
}
|
||||
|
||||
public SingleSubMod Clone(Mod mod, SingleModGroup group)
|
||||
{
|
||||
var ret = new SingleSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MultiSubMod ConvertToMulti(Mod mod, MultiModGroup group, ModPriority priority)
|
||||
{
|
||||
var ret = new MultiSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = priority,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
public (int GroupIndex, int OptionIndex) GetOptionIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
private int GetDataIndex()
|
||||
{
|
||||
var dataIndex = Group.DataContainers.IndexOf(this);
|
||||
if (dataIndex < 0)
|
||||
throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
|
||||
return dataIndex;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,352 +0,0 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Subclasses;
|
||||
|
||||
public interface IModDataOption : IModOption, IModDataContainer;
|
||||
|
||||
public class SingleSubMod(Mod mod, SingleModGroup group) : IModDataOption
|
||||
{
|
||||
internal readonly Mod Mod = mod;
|
||||
internal readonly SingleModGroup Group = group;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
|
||||
public string FullName
|
||||
=> $"{Group.Name}: {Name}";
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup IModDataContainer.Group
|
||||
=> Group;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
public SingleSubMod(Mod mod, SingleModGroup group, JToken json)
|
||||
: this(mod, group)
|
||||
{
|
||||
IModOption.Load(json, this);
|
||||
IModDataContainer.Load(json, this, mod.ModPath);
|
||||
}
|
||||
|
||||
public SingleSubMod Clone(Mod mod, SingleModGroup group)
|
||||
{
|
||||
var ret = new SingleSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public MultiSubMod ConvertToMulti(Mod mod, MultiModGroup group, ModPriority priority)
|
||||
{
|
||||
var ret = new MultiSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = priority,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
public (int GroupIndex, int OptionIndex) GetOptionIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
private int GetDataIndex()
|
||||
{
|
||||
var dataIndex = Group.DataContainers.IndexOf(this);
|
||||
if (dataIndex < 0)
|
||||
throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
|
||||
return dataIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public class MultiSubMod(Mod mod, MultiModGroup group) : IModDataOption
|
||||
{
|
||||
internal readonly Mod Mod = mod;
|
||||
internal readonly MultiModGroup Group = group;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
|
||||
public string FullName
|
||||
=> $"{Group.Name}: {Name}";
|
||||
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public ModPriority Priority { get; set; } = ModPriority.Default;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup IModDataContainer.Group
|
||||
=> Group;
|
||||
|
||||
|
||||
public MultiSubMod(Mod mod, MultiModGroup group, JToken json)
|
||||
: this(mod, group)
|
||||
{
|
||||
IModOption.Load(json, this);
|
||||
IModDataContainer.Load(json, this, mod.ModPath);
|
||||
Priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default;
|
||||
}
|
||||
|
||||
public MultiSubMod Clone(Mod mod, MultiModGroup group)
|
||||
{
|
||||
var ret = new MultiSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
Priority = Priority,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public SingleSubMod ConvertToSingle(Mod mod, SingleModGroup group)
|
||||
{
|
||||
var ret = new SingleSubMod(mod, group)
|
||||
{
|
||||
Name = Name,
|
||||
Description = Description,
|
||||
};
|
||||
IModDataContainer.Clone(this, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public static MultiSubMod CreateForSaving(string name, string description, ModPriority priority)
|
||||
=> new(null!, null!)
|
||||
{
|
||||
Name = name,
|
||||
Description = description,
|
||||
Priority = priority,
|
||||
};
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
public (int GroupIndex, int OptionIndex) GetOptionIndices()
|
||||
=> (Group.GetIndex(), GetDataIndex());
|
||||
|
||||
private int GetDataIndex()
|
||||
{
|
||||
var dataIndex = Group.DataContainers.IndexOf(this);
|
||||
if (dataIndex < 0)
|
||||
throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
|
||||
return dataIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultSubMod(IMod mod) : IModDataContainer
|
||||
{
|
||||
public const string FullName = "Default Option";
|
||||
|
||||
public string Description
|
||||
=> string.Empty;
|
||||
|
||||
internal readonly IMod Mod = mod;
|
||||
|
||||
public Dictionary<Utf8GamePath, FullPath> Files { get; set; } = [];
|
||||
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
|
||||
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
|
||||
|
||||
IMod IModDataContainer.Mod
|
||||
=> Mod;
|
||||
|
||||
IModGroup? IModDataContainer.Group
|
||||
=> null;
|
||||
|
||||
|
||||
public DefaultSubMod(Mod mod, JToken json)
|
||||
: this(mod)
|
||||
{
|
||||
IModDataContainer.Load(json, this, mod.ModPath);
|
||||
}
|
||||
|
||||
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
|
||||
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
|
||||
|
||||
public (int GroupIndex, int DataIndex) GetDataIndices()
|
||||
=> (-1, 0);
|
||||
}
|
||||
|
||||
|
||||
//public sealed class SubMod(IMod mod, IModGroup group) : IModOption
|
||||
//{
|
||||
// public string Name { get; set; } = "Default";
|
||||
//
|
||||
// public string FullName
|
||||
// => Group == null ? "Default Option" : $"{Group.Name}: {Name}";
|
||||
//
|
||||
// public string Description { get; set; } = string.Empty;
|
||||
//
|
||||
// internal readonly IMod Mod = mod;
|
||||
// internal readonly IModGroup? Group = group;
|
||||
//
|
||||
// internal (int GroupIdx, int OptionIdx) GetIndices()
|
||||
// {
|
||||
// if (IsDefault)
|
||||
// return (-1, 0);
|
||||
//
|
||||
// var groupIdx = Mod.Groups.IndexOf(Group);
|
||||
// if (groupIdx < 0)
|
||||
// throw new Exception($"Group {Group.Name} from SubMod {Name} is not contained in Mod {Mod.Name}.");
|
||||
//
|
||||
// return (groupIdx, GetOptionIndex());
|
||||
// }
|
||||
//
|
||||
// private int GetOptionIndex()
|
||||
// {
|
||||
// var optionIndex = Group switch
|
||||
// {
|
||||
// null => 0,
|
||||
// SingleModGroup single => single.OptionData.IndexOf(this),
|
||||
// MultiModGroup multi => multi.OptionData.IndexOf(p => p.Mod == this),
|
||||
// _ => throw new Exception($"Group {Group.Name} from SubMod {Name} has unknown type {typeof(Group)}"),
|
||||
// };
|
||||
// if (optionIndex < 0)
|
||||
// throw new Exception($"Group {Group!.Name} from SubMod {Name} does not contain this SubMod.");
|
||||
//
|
||||
// return optionIndex;
|
||||
// }
|
||||
//
|
||||
// public static SubMod CreateDefault(IMod mod)
|
||||
// => new(mod, null!);
|
||||
//
|
||||
// [MemberNotNullWhen(false, nameof(Group))]
|
||||
// public bool IsDefault
|
||||
// => Group == null;
|
||||
//
|
||||
// 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> FileSwapData = [];
|
||||
// public HashSet<MetaManipulation> ManipulationData = [];
|
||||
//
|
||||
// public IReadOnlyDictionary<Utf8GamePath, FullPath> Files
|
||||
// => FileData;
|
||||
//
|
||||
// public IReadOnlyDictionary<Utf8GamePath, FullPath> FileSwaps
|
||||
// => FileSwapData;
|
||||
//
|
||||
// public IReadOnlySet<MetaManipulation> Manipulations
|
||||
// => ManipulationData;
|
||||
//
|
||||
// public void Load(DirectoryInfo basePath, JToken json, out ModPriority priority)
|
||||
// {
|
||||
// FileData.Clear();
|
||||
// FileSwapData.Clear();
|
||||
// ManipulationData.Clear();
|
||||
//
|
||||
// // Every option has a name, but priorities are only relevant for multi group options.
|
||||
// Name = json[nameof(Name)]?.ToObject<string>() ?? string.Empty;
|
||||
// Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty;
|
||||
// priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? ModPriority.Default;
|
||||
//
|
||||
// var files = (JObject?)json[nameof(Files)];
|
||||
// if (files != null)
|
||||
// foreach (var property in files.Properties())
|
||||
// {
|
||||
// if (Utf8GamePath.FromString(property.Name, out var p, true))
|
||||
// FileData.TryAdd(p, new FullPath(basePath, property.Value.ToObject<Utf8RelPath>()));
|
||||
// }
|
||||
//
|
||||
// var swaps = (JObject?)json[nameof(FileSwaps)];
|
||||
// if (swaps != null)
|
||||
// foreach (var property in swaps.Properties())
|
||||
// {
|
||||
// if (Utf8GamePath.FromString(property.Name, out var p, true))
|
||||
// FileSwapData.TryAdd(p, new FullPath(property.Value.ToObject<string>()!));
|
||||
// }
|
||||
//
|
||||
// var manips = json[nameof(Manipulations)];
|
||||
// if (manips != null)
|
||||
// foreach (var s in manips.Children().Select(c => c.ToObject<MetaManipulation>())
|
||||
// .Where(m => m.Validate()))
|
||||
// ManipulationData.Add(s);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /// <summary> Create a sub mod without a mod or group only for saving it in the creator. </summary>
|
||||
// internal static SubMod CreateForSaving(string name)
|
||||
// => new(null!, null!)
|
||||
// {
|
||||
// Name = name,
|
||||
// };
|
||||
//
|
||||
//
|
||||
// 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();
|
||||
// }
|
||||
//}
|
||||
|
|
@ -2,8 +2,10 @@ using OtterGui.Classes;
|
|||
using Penumbra.Collections;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
|
|
@ -46,7 +48,7 @@ public class TemporaryMod : IMod
|
|||
=> Array.Empty<IModGroup>();
|
||||
|
||||
public TemporaryMod()
|
||||
=> Default = new(this);
|
||||
=> Default = new DefaultSubMod(this);
|
||||
|
||||
public void SetFile(Utf8GamePath gamePath, FullPath fullPath)
|
||||
=> Default.Files[gamePath] = fullPath;
|
||||
|
|
|
|||
|
|
@ -93,6 +93,10 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Mods\Subclasses\" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GetGitHash" BeforeTargets="GetAssemblyVersion" Returns="InformationalVersion">
|
||||
<Exec Command="git rev-parse --short HEAD" ConsoleToMSBuild="true" StandardOutputImportance="low" ContinueOnError="true">
|
||||
<Output TaskParameter="ExitCode" PropertyName="GitCommitHashSuccess" />
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Penumbra.Interop.Services;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.UI;
|
||||
using Penumbra.UI.Classes;
|
||||
using Penumbra.UI.ResourceWatcher;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using OtterGui.Classes;
|
|||
using OtterGui.Log;
|
||||
using OtterGui.Services;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Groups;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ using Penumbra.GameData.Enums;
|
|||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.ItemSwap;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Penumbra.GameData.Files;
|
|||
using Penumbra.Interop.ResourceTree;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ using Penumbra.Meta;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using OtterGui;
|
|||
using OtterGui.Raii;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
namespace Penumbra.UI.AdvancedWindow;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ using Penumbra.Collections.Manager;
|
|||
using Penumbra.Communication;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.Classes;
|
||||
using MessageService = Penumbra.Services.MessageService;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using Penumbra.Collections.Manager;
|
|||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Mods.Settings;
|
||||
using Penumbra.String.Classes;
|
||||
using Penumbra.UI.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ using Penumbra.Api.Enums;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Editor;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ using Penumbra.UI.Classes;
|
|||
using Dalamud.Interface.Components;
|
||||
using Penumbra.Collections.Manager;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Settings;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using OtterGui.Raii;
|
|||
using OtterGui.Widgets;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.Subclasses;
|
||||
using Penumbra.UI.AdvancedWindow;
|
||||
|
||||
namespace Penumbra.UI.ModsTab;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue