mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add a button to split a mod into separate mods for all options.
This commit is contained in:
parent
8a355e3905
commit
ff17620d85
2 changed files with 119 additions and 0 deletions
|
|
@ -7,6 +7,8 @@ using System.Linq;
|
|||
using System.Security.Cryptography;
|
||||
using Dalamud.Logging;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Structs;
|
||||
using Penumbra.Util;
|
||||
|
||||
|
|
@ -53,6 +55,105 @@ namespace Penumbra.Mod
|
|||
}
|
||||
}
|
||||
|
||||
private static DirectoryInfo CreateNewModDir( ModData mod, string optionGroup, string option )
|
||||
{
|
||||
var newName = $"{mod.BasePath.Name}_{optionGroup}_{option}";
|
||||
var newDir = TexToolsImport.CreateModFolder( new DirectoryInfo( Penumbra.Config!.ModDirectory ), newName );
|
||||
return newDir;
|
||||
}
|
||||
|
||||
private static ModData CreateNewMod( DirectoryInfo newDir, string newSortOrder )
|
||||
{
|
||||
var manager = Service< ModManager >.Get();
|
||||
manager.AddMod( newDir );
|
||||
var newMod = manager.Mods[ newDir.Name ];
|
||||
newMod.Move( newSortOrder );
|
||||
newMod.ComputeChangedItems();
|
||||
ModFileSystem.InvokeChange();
|
||||
return newMod;
|
||||
}
|
||||
|
||||
private static ModMeta CreateNewMeta( DirectoryInfo newDir, ModData mod, string name, string optionGroup, string option )
|
||||
{
|
||||
var newMeta = new ModMeta
|
||||
{
|
||||
Author = mod.Meta.Author,
|
||||
Name = name,
|
||||
Description = $"Split from {mod.Meta.Name} Group {optionGroup} Option {option}.",
|
||||
};
|
||||
var metaFile = new FileInfo( Path.Combine( newDir.FullName, "meta.json" ) );
|
||||
newMeta.SaveToFile( metaFile );
|
||||
return newMeta;
|
||||
}
|
||||
|
||||
private static void CreateModSplit( HashSet< string > unseenPaths, ModData mod, OptionGroup group, Option option )
|
||||
{
|
||||
try
|
||||
{
|
||||
var newDir = CreateNewModDir( mod, group.GroupName!, option.OptionName );
|
||||
var newName = group.SelectionType == SelectType.Multi ? $"{group.GroupName} - {option.OptionName}" : option.OptionName;
|
||||
var newMeta = CreateNewMeta( newDir, mod, newName, group.GroupName!, option.OptionName );
|
||||
foreach( var (fileName, paths) in option.OptionFiles )
|
||||
{
|
||||
var oldPath = Path.Combine( mod.BasePath.FullName, fileName );
|
||||
unseenPaths.Remove( oldPath );
|
||||
if( File.Exists( oldPath ) )
|
||||
{
|
||||
foreach( var path in paths )
|
||||
{
|
||||
var newPath = Path.Combine( newDir.FullName, path );
|
||||
Directory.CreateDirectory( Path.GetDirectoryName( newPath )! );
|
||||
File.Copy( oldPath, newPath, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var newSortOrder = group.SelectionType == SelectType.Single
|
||||
? $"{mod.SortOrder.ParentFolder.FullName}/{mod.Meta.Name}/{group.GroupName}/{option.OptionName}"
|
||||
: $"{mod.SortOrder.ParentFolder.FullName}/{mod.Meta.Name}/{group.GroupName} - {option.OptionName}";
|
||||
CreateNewMod( newDir, newSortOrder );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not split Mod:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
public static void SplitMod( ModData mod )
|
||||
{
|
||||
if( !mod.Meta.Groups.Any() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var unseenPaths = mod.Resources.ModFiles.Select( f => f.FullName ).ToHashSet();
|
||||
foreach( var group in mod.Meta.Groups.Values )
|
||||
{
|
||||
foreach( var option in group.Options )
|
||||
{
|
||||
CreateModSplit( unseenPaths, mod, group, option );
|
||||
}
|
||||
}
|
||||
|
||||
if( !unseenPaths.Any() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var defaultGroup = new OptionGroup()
|
||||
{
|
||||
GroupName = "Default",
|
||||
SelectionType = SelectType.Multi,
|
||||
};
|
||||
var defaultOption = new Option()
|
||||
{
|
||||
OptionName = "Files",
|
||||
OptionFiles = unseenPaths.ToDictionary( p => new RelPath( new FileInfo( p ), mod.BasePath ),
|
||||
p => new HashSet< GamePath >() { new( new FileInfo( p ), mod.BasePath ) } ),
|
||||
};
|
||||
CreateModSplit( unseenPaths, mod, defaultGroup, defaultOption );
|
||||
}
|
||||
|
||||
private static Option FindOrCreateDuplicates( ModMeta meta )
|
||||
{
|
||||
static Option RequiredOption()
|
||||
|
|
|
|||
|
|
@ -480,6 +480,22 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawSplitButton()
|
||||
{
|
||||
if( ImGui.Button( "Split Mod" ) )
|
||||
{
|
||||
ModCleanup.SplitMod( Mod!.Data );
|
||||
}
|
||||
|
||||
if( ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Split off all options of a mod into single mods that are placed in a collective folder.\n"
|
||||
+ "Does not remove or change the mod itself, just create (potentially inefficient) copies.\n"
|
||||
+ "Experimental - Use at own risk!" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEditLine()
|
||||
{
|
||||
DrawOpenModFolderButton();
|
||||
|
|
@ -495,6 +511,8 @@ namespace Penumbra.UI
|
|||
DrawDeduplicateButton();
|
||||
ImGui.SameLine();
|
||||
DrawNormalizeButton();
|
||||
ImGui.SameLine();
|
||||
DrawSplitButton();
|
||||
|
||||
DrawSortOrder( Mod!.Data, _modManager, _selector );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue