Let SubMods know their location in a mod.

This commit is contained in:
Ottermandias 2022-07-27 10:37:45 +02:00
parent 0b2b0d1beb
commit d6c0362404
18 changed files with 223 additions and 121 deletions

View file

@ -97,4 +97,5 @@ public interface IModGroup : IEnumerable< ISubMod >
public IModGroup Convert( SelectType type );
public bool MoveOption( int optionIdxFrom, int optionIdxTo );
public void UpdatePositions(int from = 0);
}

View file

@ -9,11 +9,14 @@ namespace Penumbra.Mods;
public interface ISubMod
{
public string Name { get; }
public string FullName { get; }
public IReadOnlyDictionary< Utf8GamePath, FullPath > Files { get; }
public IReadOnlyDictionary< Utf8GamePath, FullPath > FileSwaps { get; }
public IReadOnlySet< MetaManipulation > Manipulations { get; }
public bool IsDefault { get; }
public static void WriteSubMod( JsonWriter j, JsonSerializer serializer, ISubMod mod, DirectoryInfo basePath, int? priority )
{
j.WriteStartObject();

View file

@ -6,6 +6,7 @@ using System.Linq;
using Dalamud.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;
using OtterGui.Filesystem;
namespace Penumbra.Mods;
@ -40,7 +41,7 @@ public partial class Mod
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public static MultiModGroup? Load( JObject json, DirectoryInfo basePath )
public static MultiModGroup? Load( Mod mod, JObject json, int groupIdx )
{
var options = json[ "Options" ];
var ret = new MultiModGroup()
@ -60,11 +61,14 @@ public partial class Mod
{
if( ret.PrioritizedOptions.Count == IModGroup.MaxMultiOptions )
{
PluginLog.Warning($"Multi Group {ret.Name} has more than {IModGroup.MaxMultiOptions} options, ignoring excessive options." );
PluginLog.Warning(
$"Multi Group {ret.Name} has more than {IModGroup.MaxMultiOptions} options, ignoring excessive options." );
break;
}
var subMod = new SubMod();
subMod.Load( basePath, child, out var priority );
var subMod = new SubMod( mod );
subMod.SetPosition( groupIdx, ret.PrioritizedOptions.Count );
subMod.Load( mod.ModPath, child, out var priority );
ret.PrioritizedOptions.Add( ( subMod, priority ) );
}
}
@ -91,6 +95,22 @@ public partial class Mod
}
public bool MoveOption( int optionIdxFrom, int optionIdxTo )
=> PrioritizedOptions.Move( optionIdxFrom, optionIdxTo );
{
if( !PrioritizedOptions.Move( optionIdxFrom, optionIdxTo ) )
{
return false;
}
UpdatePositions( Math.Min( optionIdxFrom, optionIdxTo ) );
return true;
}
public void UpdatePositions( int from = 0 )
{
foreach( var ((o, _), i) in PrioritizedOptions.WithIndex().Skip( from ) )
{
o.SetPosition( o.GroupIdx, i );
}
}
}
}

View file

@ -5,6 +5,7 @@ using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;
using OtterGui.Filesystem;
namespace Penumbra.Mods;
@ -39,7 +40,7 @@ public partial class Mod
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public static SingleModGroup? Load( JObject json, DirectoryInfo basePath )
public static SingleModGroup? Load( Mod mod, JObject json, int groupIdx )
{
var options = json[ "Options" ];
var ret = new SingleModGroup
@ -57,8 +58,9 @@ public partial class Mod
{
foreach( var child in options.Children() )
{
var subMod = new SubMod();
subMod.Load( basePath, child, out _ );
var subMod = new SubMod( mod );
subMod.SetPosition( groupIdx, ret.OptionData.Count );
subMod.Load( mod.ModPath, child, out _ );
ret.OptionData.Add( subMod );
}
}
@ -85,6 +87,22 @@ public partial class Mod
}
public bool MoveOption( int optionIdxFrom, int optionIdxTo )
=> OptionData.Move( optionIdxFrom, optionIdxTo );
{
if( !OptionData.Move( optionIdxFrom, optionIdxTo ) )
{
return false;
}
UpdatePositions( Math.Min( optionIdxFrom, optionIdxTo ) );
return true;
}
public void UpdatePositions( int from = 0 )
{
foreach( var (o, i) in OptionData.WithIndex().Skip( from ) )
{
o.SetPosition( o.GroupIdx, i );
}
}
}
}

View file

@ -42,6 +42,7 @@ public partial class Mod
private void LoadDefaultOption()
{
var defaultFile = DefaultFile;
_default.SetPosition( -1, 0 );
try
{
if( !File.Exists( defaultFile ) )
@ -72,10 +73,23 @@ public partial class Mod
{
public string Name { get; set; } = "Default";
public string FullName
=> GroupIdx < 0 ? "Default Option" : $"{ParentMod.Groups[ GroupIdx ].Name}: {Name}";
internal IMod ParentMod { get; private init; }
internal int GroupIdx { get; private set; }
internal int OptionIdx { get; private set; }
public bool IsDefault
=> GroupIdx < 0;
public Dictionary< Utf8GamePath, FullPath > FileData = new();
public Dictionary< Utf8GamePath, FullPath > FileSwapData = new();
public HashSet< MetaManipulation > ManipulationData = new();
public SubMod( IMod parentMod )
=> ParentMod = parentMod;
public IReadOnlyDictionary< Utf8GamePath, FullPath > Files
=> FileData;
@ -85,25 +99,10 @@ public partial class Mod
public IReadOnlySet< MetaManipulation > Manipulations
=> ManipulationData;
// Insert all changes from the other submod.
// Overwrites already existing changes in this mod.
public void MergeIn( ISubMod other )
public void SetPosition( int groupIdx, int optionIdx )
{
foreach( var (key, value) in other.Files )
{
FileData[ key ] = value;
}
foreach( var (key, value) in other.FileSwaps )
{
FileSwapData[ key ] = value;
}
foreach( var manip in other.Manipulations )
{
ManipulationData.Remove( manip );
ManipulationData.Add( manip );
}
GroupIdx = groupIdx;
OptionIdx = optionIdx;
}
public void Load( DirectoryInfo basePath, JToken json, out int priority )