mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Merge pull request #14 from Minizbot2012/master
new meta format; enchanced grouping; minor fixes
This commit is contained in:
commit
33b5e964ef
9 changed files with 154 additions and 251 deletions
|
|
@ -1,22 +1,23 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Penumbra.Models;
|
||||||
|
|
||||||
namespace Penumbra.Importer.Models
|
namespace Penumbra.Importer.Models
|
||||||
{
|
{
|
||||||
internal class OptionList
|
internal class OptionList
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public object Description { get; set; }
|
public string Description { get; set; }
|
||||||
public string ImagePath { get; set; }
|
public string ImagePath { get; set; }
|
||||||
public List< SimpleMod > ModsJsons { get; set; }
|
public List< SimpleMod > ModsJsons { get; set; }
|
||||||
public string GroupName { get; set; }
|
public string GroupName { get; set; }
|
||||||
public string SelectionType { get; set; }
|
public SelectType SelectionType { get; set; }
|
||||||
public bool IsChecked { get; set; }
|
public bool IsChecked { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ModGroup
|
internal class ModGroup
|
||||||
{
|
{
|
||||||
public string GroupName { get; set; }
|
public string GroupName { get; set; }
|
||||||
public string SelectionType { get; set; }
|
public SelectType SelectionType { get; set; }
|
||||||
public List< OptionList > OptionList { get; set; }
|
public List< OptionList > OptionList { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,14 +211,16 @@ namespace Penumbra.Importer
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Iterate through all pages
|
// Iterate through all pages
|
||||||
foreach( var option in from modPackPage in modList.ModPackPages
|
foreach( var page in modList.ModPackPages)
|
||||||
from modGroup in modPackPage.ModGroups
|
|
||||||
from option in modGroup.OptionList
|
|
||||||
select option )
|
|
||||||
{
|
{
|
||||||
var optionFolder = new DirectoryInfo( Path.Combine( newModFolder.FullName, option.Name ) );
|
foreach(var group in page.ModGroups) {
|
||||||
ExtractSimpleModList( optionFolder, option.ModsJsons, modData );
|
var groupFolder = new DirectoryInfo(Path.Combine(newModFolder.FullName, group.GroupName));
|
||||||
AddMeta( optionFolder, newModFolder, modMeta, option.Name );
|
foreach(var option in group.OptionList) {
|
||||||
|
var optionFolder = new DirectoryInfo( Path.Combine( groupFolder.FullName, option.Name ) );
|
||||||
|
ExtractSimpleModList( optionFolder, option.ModsJsons, modData );
|
||||||
|
}
|
||||||
|
AddMeta(newModFolder, groupFolder, group, modMeta);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(
|
File.WriteAllText(
|
||||||
|
|
@ -227,19 +229,30 @@ namespace Penumbra.Importer
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMeta( DirectoryInfo optionFolder, DirectoryInfo baseFolder, ModMeta meta, string optionName )
|
private void AddMeta( DirectoryInfo baseFolder, DirectoryInfo groupFolder,ModGroup group, ModMeta meta)
|
||||||
{
|
{
|
||||||
var optionFolderLength = optionFolder.FullName.Length;
|
var Inf = new InstallerInfo
|
||||||
var baseFolderLength = baseFolder.FullName.Length;
|
|
||||||
foreach( var dir in optionFolder.EnumerateDirectories() )
|
|
||||||
{
|
{
|
||||||
foreach( var file in dir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
|
SelectionType = group.SelectionType,
|
||||||
|
GroupName = group.GroupName,
|
||||||
|
Options = new List<Option>(),
|
||||||
|
};
|
||||||
|
foreach( var opt in group.OptionList )
|
||||||
|
{
|
||||||
|
var optio = new Option
|
||||||
{
|
{
|
||||||
meta.Groups.AddFileToOtherGroups( optionName
|
OptionName = opt.Name,
|
||||||
, file.FullName.Substring( baseFolderLength ).TrimStart( '\\' )
|
OptionDesc = String.IsNullOrEmpty( opt.Description ) ? "" : opt.Description,
|
||||||
, file.FullName.Substring( optionFolderLength ).TrimStart( '\\' ).Replace( '\\', '/' ) );
|
OptionFiles = new Dictionary<string, string>()
|
||||||
|
};
|
||||||
|
var optDir = new DirectoryInfo( Path.Combine( groupFolder.FullName, opt.Name ) );
|
||||||
|
foreach( var file in optDir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
|
||||||
|
{
|
||||||
|
optio.OptionFiles[file.FullName.Substring( baseFolder.FullName.Length ).TrimStart( '\\' )] = file.FullName.Substring( optDir.FullName.Length ).TrimStart( '\\' ).Replace( '\\', '/' );
|
||||||
}
|
}
|
||||||
|
Inf.Options.Add( optio );
|
||||||
}
|
}
|
||||||
|
meta.Groups.Add( group.GroupName, Inf );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImportMetaModPack( FileInfo file )
|
private void ImportMetaModPack( FileInfo file )
|
||||||
|
|
|
||||||
|
|
@ -1,189 +1,21 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Penumbra.Models
|
namespace Penumbra.Models
|
||||||
{
|
{
|
||||||
[Serializable]
|
public enum SelectType
|
||||||
public class GroupInformation : ISerializable
|
|
||||||
{
|
{
|
||||||
// This class is just used as a temp class while (de)-serializing.
|
Single, Multi
|
||||||
// It converts the flags into lists and back.
|
}
|
||||||
[Serializable]
|
public struct Option
|
||||||
private class GroupDescription : ISerializable
|
{
|
||||||
{
|
public string OptionName;
|
||||||
public GroupDescription( GroupInformation info, (string, uint, uint, ulong) vars )
|
public string OptionDesc;
|
||||||
{
|
public Dictionary<string, string> OptionFiles;
|
||||||
GamePath = vars.Item1;
|
}
|
||||||
|
public struct InstallerInfo
|
||||||
static List< string > AddGroupTypes( ulong flags, ulong bound, List< string > groupType )
|
{
|
||||||
{
|
public string GroupName;
|
||||||
List< string > ret = null;
|
public SelectType SelectionType;
|
||||||
if( flags != uint.MaxValue )
|
public List<Option> Options;
|
||||||
{
|
|
||||||
ret = new();
|
|
||||||
for( var i = 0; i < groupType.Count; ++i )
|
|
||||||
{
|
|
||||||
var flag = 1u << i;
|
|
||||||
if( ( flags & flag ) == flag )
|
|
||||||
ret.Add( groupType[ i ] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tops and Bottoms are uint.
|
|
||||||
TopTypes = AddGroupTypes( vars.Item2, uint.MaxValue, info.TopTypes );
|
|
||||||
BottomTypes = AddGroupTypes( vars.Item3, uint.MaxValue, info.BottomTypes );
|
|
||||||
// Exclusions are the other way around and ulong.
|
|
||||||
GroupExclusions = AddGroupTypes( ~vars.Item4, 0, info.OtherGroups );
|
|
||||||
}
|
|
||||||
|
|
||||||
public (string, uint, uint, ulong) ToTuple( GroupInformation info )
|
|
||||||
{
|
|
||||||
static ulong TypesToFlags( List< string > ownTypes, List< string > globalTypes )
|
|
||||||
{
|
|
||||||
if( ownTypes == null )
|
|
||||||
return ulong.MaxValue;
|
|
||||||
|
|
||||||
ulong flags = 0;
|
|
||||||
foreach( var x in ownTypes )
|
|
||||||
{
|
|
||||||
var index = globalTypes.IndexOf( x );
|
|
||||||
if( index >= 0 )
|
|
||||||
flags |= ( 1u << index );
|
|
||||||
}
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tops = ( uint )TypesToFlags( TopTypes, info.TopTypes );
|
|
||||||
var bottoms = ( uint )TypesToFlags( BottomTypes, info.BottomTypes );
|
|
||||||
// Exclusions are the other way around.
|
|
||||||
var groupEx = ( GroupExclusions == null ) ? ulong.MaxValue : ~TypesToFlags( GroupExclusions, info.OtherGroups );
|
|
||||||
return ( GamePath, tops, bottoms, groupEx );
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GamePath { get; set; }
|
|
||||||
public List< string > TopTypes { get; set; }
|
|
||||||
public List< string > BottomTypes { get; set; }
|
|
||||||
public List< string > GroupExclusions { get; set; }
|
|
||||||
|
|
||||||
// Customize (De)-Serialization to ignore nulls.
|
|
||||||
public GroupDescription( SerializationInfo info, StreamingContext context )
|
|
||||||
{
|
|
||||||
List< string > readListOrNull( string name )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var ret = ( List< string > )info.GetValue( name, typeof( List< string > ) );
|
|
||||||
if( ret == null || ret.Count == 0 )
|
|
||||||
return null;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch( Exception )
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GamePath = info.GetString( "GamePath" );
|
|
||||||
TopTypes = readListOrNull( "TopTypes" );
|
|
||||||
BottomTypes = readListOrNull( "BottomTypes" );
|
|
||||||
GroupExclusions = readListOrNull( "GroupExclusions" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void GetObjectData( SerializationInfo info, StreamingContext context )
|
|
||||||
{
|
|
||||||
info.AddValue( "GamePath", GamePath );
|
|
||||||
if( TopTypes != null ) info.AddValue( "TopTypes", TopTypes );
|
|
||||||
if( BottomTypes != null ) info.AddValue( "BottomTypes", BottomTypes );
|
|
||||||
if( GroupExclusions != null ) info.AddValue( "GroupExclusions", GroupExclusions );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List< string > TopTypes { get; set; } = new();
|
|
||||||
public List< string > BottomTypes { get; set; } = new();
|
|
||||||
public List< string > OtherGroups { get; set; } = new();
|
|
||||||
|
|
||||||
public void AddFileToOtherGroups( string optionName, string fileName, string gamePath )
|
|
||||||
{
|
|
||||||
var idx = OtherGroups.IndexOf( optionName );
|
|
||||||
if( idx < 0 )
|
|
||||||
{
|
|
||||||
idx = OtherGroups.Count;
|
|
||||||
OtherGroups.Add( optionName );
|
|
||||||
}
|
|
||||||
|
|
||||||
(string, uint, uint, ulong) tuple = ( gamePath, uint.MaxValue, uint.MaxValue, ( 1ul << idx ) );
|
|
||||||
|
|
||||||
if( !FileToGameAndGroup.TryGetValue( fileName, out var tuple2 ) )
|
|
||||||
{
|
|
||||||
FileToGameAndGroup.Add( fileName, tuple );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tuple2.Item1 = tuple.Item1;
|
|
||||||
tuple2.Item4 |= tuple.Item4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary< string, (string, uint, uint, ulong) > FileToGameAndGroup { get; set; } = new();
|
|
||||||
|
|
||||||
public GroupInformation()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupInformation( SerializationInfo info, StreamingContext context )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
TopTypes = ( List< string > )info.GetValue( "TopTypes", TopTypes.GetType() );
|
|
||||||
}
|
|
||||||
catch( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
BottomTypes = ( List< string > )info.GetValue( "BottomTypes", BottomTypes.GetType() );
|
|
||||||
}
|
|
||||||
catch( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
OtherGroups = ( List< string > )info.GetValue( "Groups", OtherGroups.GetType() );
|
|
||||||
}
|
|
||||||
catch( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary< string, GroupDescription > dict = new();
|
|
||||||
dict = ( Dictionary< string, GroupDescription > )info.GetValue( "FileToGameAndGroups", dict.GetType() );
|
|
||||||
foreach( var pair in dict )
|
|
||||||
FileToGameAndGroup.Add( pair.Key, pair.Value.ToTuple( this ) );
|
|
||||||
}
|
|
||||||
catch( Exception )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void GetObjectData( SerializationInfo info, StreamingContext context )
|
|
||||||
{
|
|
||||||
if( ( TopTypes?.Count ?? 0 ) > 0 ) info.AddValue( "TopTypes", TopTypes );
|
|
||||||
if( ( BottomTypes?.Count ?? 0 ) > 0 ) info.AddValue( "BottomTypes", BottomTypes );
|
|
||||||
if( ( OtherGroups?.Count ?? 0 ) > 0 ) info.AddValue( "Groups", OtherGroups );
|
|
||||||
if( ( FileToGameAndGroup?.Count ?? 0 ) > 0 )
|
|
||||||
{
|
|
||||||
var dict = FileToGameAndGroup.ToDictionary( pair => pair.Key, pair => new GroupDescription( this, pair.Value ) );
|
|
||||||
info.AddValue( "FileToGameAndGroups", dict );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
||||||
namespace Penumbra.Models
|
namespace Penumbra.Models
|
||||||
|
|
@ -8,9 +9,7 @@ namespace Penumbra.Models
|
||||||
public string FolderName { get; set; }
|
public string FolderName { get; set; }
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
public int CurrentTop { get; set; } = 0;
|
public Dictionary<string, int> Conf {get;set;}
|
||||||
public int CurrentBottom { get; set; } = 0;
|
|
||||||
public int CurrentGroup { get; set; } = 0;
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public ResourceMod Mod { get; set; }
|
public ResourceMod Mod { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,6 @@ namespace Penumbra.Models
|
||||||
|
|
||||||
public Dictionary< string, string > FileSwaps { get; } = new();
|
public Dictionary< string, string > FileSwaps { get; } = new();
|
||||||
|
|
||||||
public GroupInformation Groups { get; set; } = new();
|
public Dictionary<string, InstallerInfo> Groups { get; set; } = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,9 +100,23 @@ namespace Penumbra.Mods
|
||||||
CalculateEffectiveFileList();
|
CalculateEffectiveFileList();
|
||||||
|
|
||||||
// Needed to reload body textures with mods
|
// Needed to reload body textures with mods
|
||||||
_plugin.GameUtils.ReloadPlayerResources();
|
//_plugin.GameUtils.ReloadPlayerResources();
|
||||||
|
}
|
||||||
|
private (InstallerInfo, Option, string) GlobalPosition( string rel, Dictionary<string, InstallerInfo> gps )
|
||||||
|
{
|
||||||
|
string filePath = null;
|
||||||
|
foreach( var g in gps )
|
||||||
|
{
|
||||||
|
foreach( var opt in g.Value.Options )
|
||||||
|
{
|
||||||
|
if( opt.OptionFiles.TryGetValue( rel, out filePath ) )
|
||||||
|
{
|
||||||
|
return (g.Value, opt, filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (default( InstallerInfo ), default( Option ), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateEffectiveFileList()
|
public void CalculateEffectiveFileList()
|
||||||
{
|
{
|
||||||
ResolvedFiles.Clear();
|
ResolvedFiles.Clear();
|
||||||
|
|
@ -123,23 +137,50 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
string gamePath;
|
string gamePath;
|
||||||
bool addFile = true;
|
bool addFile = true;
|
||||||
(string, uint, uint, ulong) tuple;
|
var gps = mod.Meta.Groups;
|
||||||
if( mod.Meta.Groups.FileToGameAndGroup.TryGetValue( relativeFilePath, out tuple ) )
|
if( gps.Count >= 1 )
|
||||||
{
|
{
|
||||||
gamePath = tuple.Item1;
|
var negivtron = GlobalPosition( relativeFilePath, gps );
|
||||||
var (_, tops, bottoms, excludes) = tuple;
|
if( negivtron.Item3 != null )
|
||||||
var validTop = ( ( 1u << settings.CurrentTop ) & tops ) != 0;
|
{
|
||||||
var validBottom = ( ( 1u << settings.CurrentBottom ) & bottoms ) != 0;
|
if( settings.Conf == null )
|
||||||
var validGroup = ( ( 1ul << settings.CurrentGroup ) & excludes ) != 0;
|
{
|
||||||
addFile = validTop && validBottom && validGroup;
|
settings.Conf = new();
|
||||||
|
_plugin.ModManager.Mods.Save();
|
||||||
|
}
|
||||||
|
if( !settings.Conf.ContainsKey( negivtron.Item1.GroupName ) )
|
||||||
|
{
|
||||||
|
settings.Conf[negivtron.Item1.GroupName] = 0;
|
||||||
|
_plugin.ModManager.Mods.Save();
|
||||||
|
}
|
||||||
|
var current = settings.Conf[negivtron.Item1.GroupName];
|
||||||
|
var flag = negivtron.Item1.Options.IndexOf( negivtron.Item2 );
|
||||||
|
switch( negivtron.Item1.SelectionType )
|
||||||
|
{
|
||||||
|
case SelectType.Single:
|
||||||
|
{
|
||||||
|
addFile = current == flag;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SelectType.Multi:
|
||||||
|
{
|
||||||
|
flag = 1 << negivtron.Item1.Options.IndexOf( negivtron.Item2 );
|
||||||
|
addFile = ( flag & current ) != 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gamePath = negivtron.Item3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gamePath = relativeFilePath.Replace( '\\', '/' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gamePath = relativeFilePath.Replace( '\\', '/' );
|
gamePath = relativeFilePath.Replace( '\\', '/' );
|
||||||
|
|
||||||
if( addFile )
|
if( addFile )
|
||||||
{
|
{
|
||||||
if( !ResolvedFiles.ContainsKey( gamePath ) )
|
if( !ResolvedFiles.ContainsKey( gamePath ) ) {
|
||||||
{
|
|
||||||
ResolvedFiles[ gamePath.ToLowerInvariant() ] = file;
|
ResolvedFiles[ gamePath.ToLowerInvariant() ] = file;
|
||||||
registeredFiles[ gamePath ] = mod.Meta.Name;
|
registeredFiles[ gamePath ] = mod.Meta.Name;
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +190,6 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( var swap in mod.Meta.FileSwaps )
|
foreach( var swap in mod.Meta.FileSwaps )
|
||||||
{
|
{
|
||||||
// just assume people put not fucked paths in here lol
|
// just assume people put not fucked paths in here lol
|
||||||
|
|
@ -164,6 +204,7 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_plugin.GameUtils.ReloadPlayerResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeModPriority( ModInfo info, bool up = false )
|
public void ChangeModPriority( ModInfo info, bool up = false )
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,9 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add if not in a sub-folder, otherwise it was already added.
|
// Only add if not in a sub-folder, otherwise it was already added.
|
||||||
foreach( var pair in Meta.Groups.FileToGameAndGroup )
|
//foreach( var pair in Meta.Groups.FileToGameAndGroup )
|
||||||
if (pair.Key.IndexOfAny(new[]{'/', '\\'}) < 0)
|
// if (pair.Key.IndexOfAny(new[]{'/', '\\'}) < 0)
|
||||||
ModFiles.Add( new FileInfo(Path.Combine(ModBasePath.FullName, pair.Key)) );
|
// ModFiles.Add( new FileInfo(Path.Combine(ModBasePath.FullName, pair.Key)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddConflict( string modName, string path )
|
public void AddConflict( string modName, string path )
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,8 @@ namespace Penumbra
|
||||||
ResourceLoader.Init();
|
ResourceLoader.Init();
|
||||||
ResourceLoader.Enable();
|
ResourceLoader.Enable();
|
||||||
|
|
||||||
|
GameUtils.ReloadPlayerResources();
|
||||||
|
|
||||||
SettingsInterface = new SettingsInterface( this );
|
SettingsInterface = new SettingsInterface( this );
|
||||||
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -598,36 +598,48 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
private void DrawGroupSelectors()
|
private void DrawGroupSelectors()
|
||||||
{
|
{
|
||||||
var hasTopTypes = ( _selectedMod.Mod.Meta.Groups.TopTypes?.Count ?? 0 ) > 1;
|
//Spahetti code time
|
||||||
var hasBottomTypes = ( _selectedMod.Mod.Meta.Groups.BottomTypes?.Count ?? 0 ) > 1;
|
var mod = _plugin.SettingsInterface._selectedMod;
|
||||||
var hasGroups = ( _selectedMod.Mod.Meta.Groups.OtherGroups?.Count ?? 0 ) > 1;
|
var conf = mod.Conf;
|
||||||
var numSelectors = ( hasTopTypes ? 1 : 0 ) + ( hasBottomTypes ? 1 : 0 ) + ( hasGroups ? 1 : 0 );
|
var settings = mod.Mod.Meta.Groups;
|
||||||
var selectorWidth = ( ImGui.GetWindowWidth()
|
foreach( var g in settings )
|
||||||
- ( hasTopTypes ? ImGui.CalcTextSize( "Top " ).X : 0 )
|
|
||||||
- ( hasBottomTypes ? ImGui.CalcTextSize( "Bottom " ).X : 0 )
|
|
||||||
- ( hasGroups ? ImGui.CalcTextSize( "Group " ).X : 0 ) ) / numSelectors;
|
|
||||||
|
|
||||||
void DrawSelector( string label, string propertyName, System.Collections.Generic.List< string > list, bool sameLine )
|
|
||||||
{
|
{
|
||||||
var current = ( int )_selectedMod.GetType().GetProperty( propertyName ).GetValue( _selectedMod );
|
switch( g.Value.SelectionType )
|
||||||
ImGui.SetNextItemWidth( selectorWidth );
|
|
||||||
if( sameLine ) ImGui.SameLine();
|
|
||||||
if( ImGui.Combo( label, ref current, list.ToArray(), list.Count() ) )
|
|
||||||
{
|
{
|
||||||
_selectedMod.GetType().GetProperty( propertyName ).SetValue( _selectedMod, current );
|
case SelectType.Multi:
|
||||||
_plugin.ModManager.Mods.Save();
|
{
|
||||||
_plugin.ModManager.CalculateEffectiveFileList();
|
var i = 0;
|
||||||
|
var flag = conf[g.Key];
|
||||||
|
foreach( var opt in g.Value.Options )
|
||||||
|
{
|
||||||
|
var enab = ( flag & 1 << i ) != 0;
|
||||||
|
if( ImGui.Checkbox( g.Value.GroupName + " - " + opt.OptionName, ref enab ) )
|
||||||
|
{
|
||||||
|
flag = flag ^= 1 << i;
|
||||||
|
conf[g.Key] = flag;
|
||||||
|
_plugin.ModManager.Mods.Save();
|
||||||
|
_plugin.ModManager.CalculateEffectiveFileList();
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SelectType.Single:
|
||||||
|
{
|
||||||
|
var code = conf[g.Key];
|
||||||
|
if( g.Value.Options.Count > 1 )
|
||||||
|
{
|
||||||
|
if( ImGui.Combo( g.Value.GroupName, ref code, g.Value.Options.Select( x => x.OptionName ).ToArray(), g.Value.Options.ToArray().Length ) )
|
||||||
|
{
|
||||||
|
conf[g.Key] = code;
|
||||||
|
_plugin.ModManager.Mods.Save();
|
||||||
|
_plugin.ModManager.CalculateEffectiveFileList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasTopTypes )
|
|
||||||
DrawSelector( "Top", "CurrentTop", _selectedMod.Mod.Meta.Groups.TopTypes, false );
|
|
||||||
|
|
||||||
if( hasBottomTypes )
|
|
||||||
DrawSelector( "Bottom", "CurrentBottom", _selectedMod.Mod.Meta.Groups.BottomTypes, hasTopTypes );
|
|
||||||
|
|
||||||
if( hasGroups )
|
|
||||||
DrawSelector( "Group", "CurrentGroup", _selectedMod.Mod.Meta.Groups.OtherGroups, numSelectors > 1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawInstalledMods()
|
void DrawInstalledMods()
|
||||||
|
|
@ -692,8 +704,6 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
DrawEditButtons();
|
DrawEditButtons();
|
||||||
|
|
||||||
DrawGroupSelectors();
|
|
||||||
|
|
||||||
ImGui.BeginTabBar( "PenumbraPluginDetails" );
|
ImGui.BeginTabBar( "PenumbraPluginDetails" );
|
||||||
|
|
||||||
if( _selectedMod.Mod.Meta.Description?.Length > 0 && ImGui.BeginTabItem( "About" ) )
|
if( _selectedMod.Mod.Meta.Description?.Length > 0 && ImGui.BeginTabItem( "About" ) )
|
||||||
|
|
@ -714,7 +724,12 @@ namespace Penumbra.UI
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(_selectedMod.Mod.Meta.Groups.Count >=1) {
|
||||||
|
if(ImGui.BeginTabItem( "Configuration" )) {
|
||||||
|
DrawGroupSelectors();
|
||||||
|
ImGui.EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
if( ImGui.BeginTabItem( "Files" ) )
|
if( ImGui.BeginTabItem( "Files" ) )
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth( -1 );
|
ImGui.SetNextItemWidth( -1 );
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue