mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-15 13:14:17 +01:00
Add mod setting API functions.
This commit is contained in:
parent
df1a75b58a
commit
c578bd3a49
5 changed files with 245 additions and 39 deletions
|
|
@ -29,13 +29,14 @@ public enum PenumbraApiEc
|
||||||
CollectionMissing = 2,
|
CollectionMissing = 2,
|
||||||
ModMissing = 3,
|
ModMissing = 3,
|
||||||
OptionGroupMissing = 4,
|
OptionGroupMissing = 4,
|
||||||
SettingMissing = 5,
|
OptionMissing = 5,
|
||||||
|
|
||||||
CharacterCollectionExists = 6,
|
CharacterCollectionExists = 6,
|
||||||
LowerPriority = 7,
|
LowerPriority = 7,
|
||||||
InvalidGamePath = 8,
|
InvalidGamePath = 8,
|
||||||
FileMissing = 9,
|
FileMissing = 9,
|
||||||
InvalidManipulation = 10,
|
InvalidManipulation = 10,
|
||||||
|
InvalidArgument = 11,
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IPenumbraApi : IPenumbraApiBase
|
public interface IPenumbraApi : IPenumbraApiBase
|
||||||
|
|
@ -75,7 +76,7 @@ public interface IPenumbraApi : IPenumbraApiBase
|
||||||
public string ResolvePath( string gamePath, string characterName );
|
public string ResolvePath( string gamePath, string characterName );
|
||||||
|
|
||||||
// Reverse resolves a given modded local path into its replacement in form of all applicable game path for given character
|
// Reverse resolves a given modded local path into its replacement in form of all applicable game path for given character
|
||||||
public IList<string> ReverseResolvePath( string moddedPath, string characterName );
|
public IList< string > ReverseResolvePath( string moddedPath, string characterName );
|
||||||
|
|
||||||
// Try to load a given gamePath with the resolved path from Penumbra.
|
// Try to load a given gamePath with the resolved path from Penumbra.
|
||||||
public T? GetFile< T >( string gamePath ) where T : FileResource;
|
public T? GetFile< T >( string gamePath ) where T : FileResource;
|
||||||
|
|
@ -109,12 +110,12 @@ public interface IPenumbraApi : IPenumbraApiBase
|
||||||
|
|
||||||
// Obtain the potential settings of a mod specified by its directory name first or mod name second.
|
// Obtain the potential settings of a mod specified by its directory name first or mod name second.
|
||||||
// Returns null if the mod could not be found.
|
// Returns null if the mod could not be found.
|
||||||
public IDictionary< string, (IList<string>, SelectType) >? GetAvailableModSettings( string modDirectory, string modName );
|
public IDictionary< string, (IList< string >, SelectType) >? GetAvailableModSettings( string modDirectory, string modName );
|
||||||
|
|
||||||
// Obtain the enabled state, the priority, the settings of a mod specified by its directory name first or mod name second,
|
// Obtain the enabled state, the priority, the settings of a mod specified by its directory name first or mod name second,
|
||||||
// and whether these settings are inherited, or null if the collection does not set them at all.
|
// and whether these settings are inherited, or null if the collection does not set them at all.
|
||||||
// If allowInheritance is false, only the collection itself will be checked.
|
// If allowInheritance is false, only the collection itself will be checked.
|
||||||
public (PenumbraApiEc, (bool, int, IDictionary< string, IList<string> >, bool)?) GetCurrentModSettings( string collectionName,
|
public (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) GetCurrentModSettings( string collectionName,
|
||||||
string modDirectory, string modName, bool allowInheritance );
|
string modDirectory, string modName, bool allowInheritance );
|
||||||
|
|
||||||
// Try to set the inheritance state in the given collection of a mod specified by its directory name first or mod name second.
|
// Try to set the inheritance state in the given collection of a mod specified by its directory name first or mod name second.
|
||||||
|
|
@ -136,7 +137,7 @@ public interface IPenumbraApi : IPenumbraApiBase
|
||||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, string option );
|
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, string option );
|
||||||
|
|
||||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
||||||
IReadOnlyList<string> options );
|
IReadOnlyList< string > options );
|
||||||
|
|
||||||
|
|
||||||
// Create a temporary collection without actual settings but with a cache.
|
// Create a temporary collection without actual settings but with a cache.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
@ -12,12 +13,15 @@ using Penumbra.Collections;
|
||||||
using Penumbra.GameData.ByteString;
|
using Penumbra.GameData.ByteString;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Api;
|
namespace Penumbra.Api;
|
||||||
|
|
||||||
public class PenumbraApi : IDisposable, IPenumbraApi
|
public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
{
|
{
|
||||||
public int ApiVersion { get; } = 4;
|
public int ApiVersion
|
||||||
|
=> 4;
|
||||||
|
|
||||||
private Penumbra? _penumbra;
|
private Penumbra? _penumbra;
|
||||||
private Lumina.GameData? _lumina;
|
private Lumina.GameData? _lumina;
|
||||||
public event GameObjectRedrawn? GameObjectRedrawn;
|
public event GameObjectRedrawn? GameObjectRedrawn;
|
||||||
|
|
@ -231,28 +235,173 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDictionary< string, (IList< string >, SelectType) >? GetAvailableModSettings( string modDirectory, string modName )
|
public IDictionary< string, (IList< string >, SelectType) >? GetAvailableModSettings( string modDirectory, string modName )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
return Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod )
|
||||||
|
? mod.Groups.ToDictionary( g => g.Name, g => ( ( IList< string > )g.Select( o => o.Name ).ToList(), g.Type ) )
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
public (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) GetCurrentModSettings( string collectionName,
|
public (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) GetCurrentModSettings( string collectionName,
|
||||||
string modDirectory, string modName,
|
string modDirectory, string modName, bool allowInheritance )
|
||||||
bool allowInheritance )
|
{
|
||||||
=> throw new NotImplementedException();
|
CheckInitialized();
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.CollectionMissing, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.ModMissing, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
var settings = allowInheritance ? collection.Settings[ mod.Index ] : collection[ mod.Index ].Settings;
|
||||||
|
if( settings == null )
|
||||||
|
{
|
||||||
|
return ( PenumbraApiEc.Okay, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
var shareSettings = settings.ConvertToShareable( mod );
|
||||||
|
return ( PenumbraApiEc.Okay,
|
||||||
|
( shareSettings.Enabled, shareSettings.Priority, shareSettings.Settings, collection.Settings[ mod.Index ] != null ) );
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc TryInheritMod( string collectionName, string modDirectory, string modName, bool inherit )
|
public PenumbraApiEc TryInheritMod( string collectionName, string modDirectory, string modName, bool inherit )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.CollectionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.ModMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return collection.SetModInheritance( mod.Index, inherit ) ? PenumbraApiEc.Okay : PenumbraApiEc.NothingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc TrySetMod( string collectionName, string modDirectory, string modName, bool enabled )
|
public PenumbraApiEc TrySetMod( string collectionName, string modDirectory, string modName, bool enabled )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.CollectionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.ModMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection.SetModState( mod.Index, enabled ) ? PenumbraApiEc.Okay : PenumbraApiEc.NothingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc TrySetModPriority( string collectionName, string modDirectory, string modName, int priority )
|
public PenumbraApiEc TrySetModPriority( string collectionName, string modDirectory, string modName, int priority )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.CollectionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, string option )
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
return PenumbraApiEc.ModMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection.SetModPriority( mod.Index, priority ) ? PenumbraApiEc.Okay : PenumbraApiEc.NothingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
||||||
IReadOnlyList< string > options )
|
string optionName )
|
||||||
=> throw new NotImplementedException();
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.CollectionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.ModMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupIdx = mod.Groups.IndexOf( g => g.Name == optionGroupName );
|
||||||
|
if( groupIdx < 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.OptionGroupMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
var optionIdx = mod.Groups[ groupIdx ].IndexOf( o => o.Name == optionName );
|
||||||
|
if( optionIdx < 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.OptionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
var setting = mod.Groups[ groupIdx ].Type == SelectType.Multi ? 1u << optionIdx : ( uint )optionIdx;
|
||||||
|
|
||||||
|
return collection.SetModSetting( mod.Index, groupIdx, setting ) ? PenumbraApiEc.Okay : PenumbraApiEc.NothingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
||||||
|
IReadOnlyList< string > optionNames )
|
||||||
|
{
|
||||||
|
CheckInitialized();
|
||||||
|
if( optionNames.Count == 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.InvalidArgument;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.CollectionManager.ByName( collectionName, out var collection ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.CollectionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.ModMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupIdx = mod.Groups.IndexOf( g => g.Name == optionGroupName );
|
||||||
|
if( groupIdx < 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.OptionGroupMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
var group = mod.Groups[ groupIdx ];
|
||||||
|
|
||||||
|
uint setting = 0;
|
||||||
|
if( group.Type == SelectType.Single )
|
||||||
|
{
|
||||||
|
var name = optionNames[ ^1 ];
|
||||||
|
var optionIdx = group.IndexOf( o => o.Name == name );
|
||||||
|
if( optionIdx < 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.OptionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting = ( uint )optionIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach( var name in optionNames )
|
||||||
|
{
|
||||||
|
var optionIdx = group.IndexOf( o => o.Name == name );
|
||||||
|
if( optionIdx < 0 )
|
||||||
|
{
|
||||||
|
return PenumbraApiEc.OptionMissing;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting |= 1u << optionIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collection.SetModSetting( mod.Index, groupIdx, setting ) ? PenumbraApiEc.Okay : PenumbraApiEc.NothingChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public PenumbraApiEc CreateTemporaryCollection( string collectionName, string? character, bool forceOverwriteCharacter )
|
public PenumbraApiEc CreateTemporaryCollection( string collectionName, string? character, bool forceOverwriteCharacter )
|
||||||
=> throw new NotImplementedException();
|
=> throw new NotImplementedException();
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,20 @@ public partial class ModCollection
|
||||||
public event ModSettingChangeDelegate ModSettingChanged;
|
public event ModSettingChangeDelegate ModSettingChanged;
|
||||||
|
|
||||||
// Enable or disable the mod inheritance of mod idx.
|
// Enable or disable the mod inheritance of mod idx.
|
||||||
public void SetModInheritance( int idx, bool inherit )
|
public bool SetModInheritance( int idx, bool inherit )
|
||||||
{
|
{
|
||||||
if( FixInheritance( idx, inherit ) )
|
if( FixInheritance( idx, inherit ) )
|
||||||
{
|
{
|
||||||
ModSettingChanged.Invoke( ModSettingChange.Inheritance, idx, inherit ? 0 : 1, 0, false );
|
ModSettingChanged.Invoke( ModSettingChange.Inheritance, idx, inherit ? 0 : 1, 0, false );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the enabled state mod idx to newValue if it differs from the current enabled state.
|
// Set the enabled state mod idx to newValue if it differs from the current enabled state.
|
||||||
// If mod idx is currently inherited, stop the inheritance.
|
// If mod idx is currently inherited, stop the inheritance.
|
||||||
public void SetModState( int idx, bool newValue )
|
public bool SetModState( int idx, bool newValue )
|
||||||
{
|
{
|
||||||
var oldValue = _settings[ idx ]?.Enabled ?? this[ idx ].Settings?.Enabled ?? false;
|
var oldValue = _settings[ idx ]?.Enabled ?? this[ idx ].Settings?.Enabled ?? false;
|
||||||
if( newValue != oldValue )
|
if( newValue != oldValue )
|
||||||
|
|
@ -42,7 +45,10 @@ public partial class ModCollection
|
||||||
var inheritance = FixInheritance( idx, false );
|
var inheritance = FixInheritance( idx, false );
|
||||||
_settings[ idx ]!.Enabled = newValue;
|
_settings[ idx ]!.Enabled = newValue;
|
||||||
ModSettingChanged.Invoke( ModSettingChange.EnableState, idx, inheritance ? -1 : newValue ? 0 : 1, 0, false );
|
ModSettingChanged.Invoke( ModSettingChange.EnableState, idx, inheritance ? -1 : newValue ? 0 : 1, 0, false );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable or disable the mod inheritance of every mod in mods.
|
// Enable or disable the mod inheritance of every mod in mods.
|
||||||
|
|
@ -78,7 +84,7 @@ public partial class ModCollection
|
||||||
|
|
||||||
// Set the priority of mod idx to newValue if it differs from the current priority.
|
// Set the priority of mod idx to newValue if it differs from the current priority.
|
||||||
// If mod idx is currently inherited, stop the inheritance.
|
// If mod idx is currently inherited, stop the inheritance.
|
||||||
public void SetModPriority( int idx, int newValue )
|
public bool SetModPriority( int idx, int newValue )
|
||||||
{
|
{
|
||||||
var oldValue = _settings[ idx ]?.Priority ?? this[ idx ].Settings?.Priority ?? 0;
|
var oldValue = _settings[ idx ]?.Priority ?? this[ idx ].Settings?.Priority ?? 0;
|
||||||
if( newValue != oldValue )
|
if( newValue != oldValue )
|
||||||
|
|
@ -86,12 +92,15 @@ public partial class ModCollection
|
||||||
var inheritance = FixInheritance( idx, false );
|
var inheritance = FixInheritance( idx, false );
|
||||||
_settings[ idx ]!.Priority = newValue;
|
_settings[ idx ]!.Priority = newValue;
|
||||||
ModSettingChanged.Invoke( ModSettingChange.Priority, idx, inheritance ? -1 : oldValue, 0, false );
|
ModSettingChanged.Invoke( ModSettingChange.Priority, idx, inheritance ? -1 : oldValue, 0, false );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set a given setting group settingName of mod idx to newValue if it differs from the current value and fix it if necessary.
|
// Set a given setting group settingName of mod idx to newValue if it differs from the current value and fix it if necessary.
|
||||||
// If mod idx is currently inherited, stop the inheritance.
|
// If mod idx is currently inherited, stop the inheritance.
|
||||||
public void SetModSetting( int idx, int groupIdx, uint newValue )
|
public bool SetModSetting( int idx, int groupIdx, uint newValue )
|
||||||
{
|
{
|
||||||
var settings = _settings[ idx ] != null ? _settings[ idx ]!.Settings : this[ idx ].Settings?.Settings;
|
var settings = _settings[ idx ] != null ? _settings[ idx ]!.Settings : this[ idx ].Settings?.Settings;
|
||||||
var oldValue = settings?[ groupIdx ] ?? 0;
|
var oldValue = settings?[ groupIdx ] ?? 0;
|
||||||
|
|
@ -100,31 +109,26 @@ public partial class ModCollection
|
||||||
var inheritance = FixInheritance( idx, false );
|
var inheritance = FixInheritance( idx, false );
|
||||||
_settings[ idx ]!.SetValue( Penumbra.ModManager[ idx ], groupIdx, newValue );
|
_settings[ idx ]!.SetValue( Penumbra.ModManager[ idx ], groupIdx, newValue );
|
||||||
ModSettingChanged.Invoke( ModSettingChange.Setting, idx, inheritance ? -1 : ( int )oldValue, groupIdx, false );
|
ModSettingChanged.Invoke( ModSettingChange.Setting, idx, inheritance ? -1 : ( int )oldValue, groupIdx, false );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change one of the available mod settings for mod idx discerned by type.
|
// Change one of the available mod settings for mod idx discerned by type.
|
||||||
// If type == Setting, settingName should be a valid setting for that mod, otherwise it will be ignored.
|
// If type == Setting, settingName should be a valid setting for that mod, otherwise it will be ignored.
|
||||||
// The setting will also be automatically fixed if it is invalid for that setting group.
|
// The setting will also be automatically fixed if it is invalid for that setting group.
|
||||||
// For boolean parameters, newValue == 0 will be treated as false and != 0 as true.
|
// For boolean parameters, newValue == 0 will be treated as false and != 0 as true.
|
||||||
public void ChangeModSetting( ModSettingChange type, int idx, int newValue, int groupIdx )
|
public bool ChangeModSetting( ModSettingChange type, int idx, int newValue, int groupIdx )
|
||||||
{
|
{
|
||||||
switch( type )
|
return type switch
|
||||||
{
|
{
|
||||||
case ModSettingChange.Inheritance:
|
ModSettingChange.Inheritance => SetModInheritance( idx, newValue != 0 ),
|
||||||
SetModInheritance( idx, newValue != 0 );
|
ModSettingChange.EnableState => SetModState( idx, newValue != 0 ),
|
||||||
break;
|
ModSettingChange.Priority => SetModPriority( idx, newValue ),
|
||||||
case ModSettingChange.EnableState:
|
ModSettingChange.Setting => SetModSetting( idx, groupIdx, ( uint )newValue ),
|
||||||
SetModState( idx, newValue != 0 );
|
_ => throw new ArgumentOutOfRangeException( nameof( type ), type, null ),
|
||||||
break;
|
};
|
||||||
case ModSettingChange.Priority:
|
|
||||||
SetModPriority( idx, newValue );
|
|
||||||
break;
|
|
||||||
case ModSettingChange.Setting:
|
|
||||||
SetModSetting( idx, groupIdx, ( uint )newValue );
|
|
||||||
break;
|
|
||||||
default: throw new ArgumentOutOfRangeException( nameof( type ), type, null );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set inheritance of a mod without saving,
|
// Set inheritance of a mod without saving,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods;
|
||||||
|
|
||||||
|
|
@ -37,5 +38,28 @@ public sealed partial class Mod
|
||||||
ModOptionChanged += OnModOptionChange;
|
ModOptionChanged += OnModOptionChange;
|
||||||
ModPathChanged += OnModPathChange;
|
ModPathChanged += OnModPathChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Try to obtain a mod by its directory name (unique identifier, preferred),
|
||||||
|
// or the first mod of the given name if no directory fits.
|
||||||
|
public bool TryGetMod( string modDirectory, string modName, [NotNullWhen( true )] out Mod? mod )
|
||||||
|
{
|
||||||
|
mod = null;
|
||||||
|
foreach( var m in _mods )
|
||||||
|
{
|
||||||
|
if( m.ModPath.Name == modDirectory )
|
||||||
|
{
|
||||||
|
mod = m;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m.Name == modName )
|
||||||
|
{
|
||||||
|
mod ??= m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod != null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods;
|
||||||
|
|
||||||
|
|
@ -10,7 +11,7 @@ namespace Penumbra.Mods;
|
||||||
public class ModSettings
|
public class ModSettings
|
||||||
{
|
{
|
||||||
public static readonly ModSettings Empty = new();
|
public static readonly ModSettings Empty = new();
|
||||||
public List< uint > Settings { get; init; } = new();
|
public List< uint > Settings { get; private init; } = new();
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
||||||
|
|
@ -100,7 +101,7 @@ public class ModSettings
|
||||||
private static uint FixSetting( IModGroup group, uint value )
|
private static uint FixSetting( IModGroup group, uint value )
|
||||||
=> group.Type switch
|
=> group.Type switch
|
||||||
{
|
{
|
||||||
SelectType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
SelectType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
||||||
SelectType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
SelectType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
||||||
_ => value,
|
_ => value,
|
||||||
};
|
};
|
||||||
|
|
@ -208,4 +209,31 @@ public class ModSettings
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the settings for a given mod in a shareable format, using the names of groups and options instead of indices.
|
||||||
|
// Does not repair settings but ignores settings not fitting to the given mod.
|
||||||
|
public (bool Enabled, int Priority, Dictionary< string, IList< string > > Settings) ConvertToShareable( Mod mod )
|
||||||
|
{
|
||||||
|
var dict = new Dictionary< string, IList< string > >( Settings.Count );
|
||||||
|
foreach( var (setting, idx) in Settings.WithIndex() )
|
||||||
|
{
|
||||||
|
if( idx >= mod.Groups.Count )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var group = mod.Groups[ idx ];
|
||||||
|
if( group.Type == SelectType.Single && setting < group.Count )
|
||||||
|
{
|
||||||
|
dict.Add( group.Name, new[] { group[ ( int )setting ].Name } );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var list = group.Where( ( _, optionIdx ) => ( setting & ( 1 << optionIdx ) ) != 0 ).Select( o => o.Name ).ToList();
|
||||||
|
dict.Add( group.Name, list );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( Enabled, Priority, dict );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue