mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Change everything in collection caches to use IMod and introduce TemporaryMod.
This commit is contained in:
parent
c578bd3a49
commit
fc767589a2
18 changed files with 129 additions and 74 deletions
|
|
@ -378,7 +378,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
if( group.Type == SelectType.Single )
|
||||
{
|
||||
var name = optionNames[ ^1 ];
|
||||
var optionIdx = group.IndexOf( o => o.Name == name );
|
||||
var optionIdx = group.IndexOf( o => o.Name == optionNames[^1] );
|
||||
if( optionIdx < 0 )
|
||||
{
|
||||
return PenumbraApiEc.OptionMissing;
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ public partial class ModCollection
|
|||
internal IReadOnlyDictionary< Utf8GamePath, ModPath > ResolvedFiles
|
||||
=> _cache?.ResolvedFiles ?? new Dictionary< Utf8GamePath, ModPath >();
|
||||
|
||||
internal IReadOnlyDictionary< string, (SingleArray< Mod >, object?) > ChangedItems
|
||||
=> _cache?.ChangedItems ?? new Dictionary< string, (SingleArray< Mod >, object?) >();
|
||||
internal IReadOnlyDictionary< string, (SingleArray< IMod >, object?) > ChangedItems
|
||||
=> _cache?.ChangedItems ?? new Dictionary< string, (SingleArray< IMod >, object?) >();
|
||||
|
||||
internal IEnumerable< SingleArray< ModConflicts > > AllConflicts
|
||||
=> _cache?.AllConflicts ?? Array.Empty< SingleArray< ModConflicts > >();
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ using Penumbra.Util;
|
|||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
public record struct ModPath( Mod Mod, FullPath Path );
|
||||
public record ModConflicts( Mod Mod2, List< object > Conflicts, bool HasPriority, bool Solved );
|
||||
public record struct ModPath( IMod Mod, FullPath Path );
|
||||
public record ModConflicts( IMod Mod2, List< object > Conflicts, bool HasPriority, bool Solved );
|
||||
|
||||
public partial class ModCollection
|
||||
{
|
||||
|
|
@ -21,15 +21,15 @@ public partial class ModCollection
|
|||
private class Cache : IDisposable
|
||||
{
|
||||
private readonly ModCollection _collection;
|
||||
private readonly SortedList< string, (SingleArray< Mod >, object?) > _changedItems = new();
|
||||
private readonly SortedList< string, (SingleArray< IMod >, object?) > _changedItems = new();
|
||||
public readonly Dictionary< Utf8GamePath, ModPath > ResolvedFiles = new();
|
||||
public readonly MetaManager MetaManipulations;
|
||||
private readonly Dictionary< Mod, SingleArray< ModConflicts > > _conflicts = new();
|
||||
private readonly Dictionary< IMod, SingleArray< ModConflicts > > _conflicts = new();
|
||||
|
||||
public IEnumerable< SingleArray< ModConflicts > > AllConflicts
|
||||
=> _conflicts.Values;
|
||||
|
||||
public SingleArray< ModConflicts > Conflicts( Mod mod )
|
||||
public SingleArray< ModConflicts > Conflicts( IMod mod )
|
||||
=> _conflicts.TryGetValue( mod, out var c ) ? c : new SingleArray< ModConflicts >();
|
||||
|
||||
// Count the number of changes of the effective file list.
|
||||
|
|
@ -38,7 +38,7 @@ public partial class ModCollection
|
|||
private int _changedItemsSaveCounter = -1;
|
||||
|
||||
// Obtain currently changed items. Computes them if they haven't been computed before.
|
||||
public IReadOnlyDictionary< string, (SingleArray< Mod >, object?) > ChangedItems
|
||||
public IReadOnlyDictionary< string, (SingleArray< IMod >, object?) > ChangedItems
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
@ -178,13 +178,13 @@ public partial class ModCollection
|
|||
}
|
||||
}
|
||||
|
||||
public void ReloadMod( Mod mod, bool addMetaChanges )
|
||||
public void ReloadMod( IMod mod, bool addMetaChanges )
|
||||
{
|
||||
RemoveMod( mod, addMetaChanges );
|
||||
AddMod( mod, addMetaChanges );
|
||||
}
|
||||
|
||||
public void RemoveMod( Mod mod, bool addMetaChanges )
|
||||
public void RemoveMod( IMod mod, bool addMetaChanges )
|
||||
{
|
||||
var conflicts = Conflicts( mod );
|
||||
|
||||
|
|
@ -243,37 +243,40 @@ public partial class ModCollection
|
|||
|
||||
|
||||
// Add all files and possibly manipulations of a given mod according to its settings in this collection.
|
||||
public void AddMod( Mod mod, bool addMetaChanges )
|
||||
public void AddMod( IMod mod, bool addMetaChanges )
|
||||
{
|
||||
var settings = _collection[ mod.Index ].Settings;
|
||||
if( settings is not { Enabled: true } )
|
||||
if( mod.Index >= 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach( var (group, groupIndex) in mod.Groups.WithIndex().OrderByDescending( g => g.Item1.Priority ) )
|
||||
{
|
||||
if( group.Count == 0 )
|
||||
var settings = _collection[ mod.Index ].Settings;
|
||||
if( settings is not { Enabled: true } )
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
var config = settings.Settings[ groupIndex ];
|
||||
switch( group.Type )
|
||||
foreach( var (group, groupIndex) in mod.Groups.WithIndex().OrderByDescending( g => g.Item1.Priority ) )
|
||||
{
|
||||
case SelectType.Single:
|
||||
AddSubMod( group[ ( int )config ], mod );
|
||||
break;
|
||||
case SelectType.Multi:
|
||||
if( group.Count == 0 )
|
||||
{
|
||||
foreach( var (option, _) in group.WithIndex()
|
||||
.OrderByDescending( p => group.OptionPriority( p.Item2 ) )
|
||||
.Where( p => ( ( 1 << p.Item2 ) & config ) != 0 ) )
|
||||
{
|
||||
AddSubMod( option, mod );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
var config = settings.Settings[ groupIndex ];
|
||||
switch( group.Type )
|
||||
{
|
||||
case SelectType.Single:
|
||||
AddSubMod( group[ ( int )config ], mod );
|
||||
break;
|
||||
case SelectType.Multi:
|
||||
{
|
||||
foreach( var (option, _) in group.WithIndex()
|
||||
.OrderByDescending( p => group.OptionPriority( p.Item2 ) )
|
||||
.Where( p => ( ( 1 << p.Item2 ) & config ) != 0 ) )
|
||||
{
|
||||
AddSubMod( option, mod );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -297,7 +300,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
// Add all files and possibly manipulations of a specific submod
|
||||
private void AddSubMod( ISubMod subMod, Mod parentMod )
|
||||
private void AddSubMod( ISubMod subMod, IMod parentMod )
|
||||
{
|
||||
foreach( var (path, file) in subMod.Files.Concat( subMod.FileSwaps ) )
|
||||
{
|
||||
|
|
@ -320,7 +323,7 @@ public partial class ModCollection
|
|||
// For different mods, higher mod priority takes precedence before option group priority,
|
||||
// which takes precedence before option priority, which takes precedence before ordering.
|
||||
// Inside the same mod, conflicts are not recorded.
|
||||
private void AddFile( Utf8GamePath path, FullPath file, Mod mod )
|
||||
private void AddFile( Utf8GamePath path, FullPath file, IMod mod )
|
||||
{
|
||||
if( ResolvedFiles.TryAdd( path, new ModPath( mod, file ) ) )
|
||||
{
|
||||
|
|
@ -343,7 +346,7 @@ public partial class ModCollection
|
|||
|
||||
// Remove all empty conflict sets for a given mod with the given conflicts.
|
||||
// If transitive is true, also removes the corresponding version of the other mod.
|
||||
private void RemoveEmptyConflicts( Mod mod, SingleArray< ModConflicts > oldConflicts, bool transitive )
|
||||
private void RemoveEmptyConflicts( IMod mod, SingleArray< ModConflicts > oldConflicts, bool transitive )
|
||||
{
|
||||
var changedConflicts = oldConflicts.Remove( c =>
|
||||
{
|
||||
|
|
@ -372,10 +375,10 @@ public partial class ModCollection
|
|||
// Add a new conflict between the added mod and the existing mod.
|
||||
// Update all other existing conflicts between the existing mod and other mods if necessary.
|
||||
// Returns if the added mod takes priority before the existing mod.
|
||||
private bool AddConflict( object data, Mod addedMod, Mod existingMod )
|
||||
private bool AddConflict( object data, IMod addedMod, IMod existingMod )
|
||||
{
|
||||
var addedPriority = addedMod.Index >= 0 ? _collection[ addedMod.Index ].Settings!.Priority : int.MaxValue;
|
||||
var existingPriority = existingMod.Index >= 0 ? _collection[ existingMod.Index ].Settings!.Priority : int.MaxValue;
|
||||
var addedPriority = addedMod.Index >= 0 ? _collection[ addedMod.Index ].Settings!.Priority : addedMod.Priority;
|
||||
var existingPriority = existingMod.Index >= 0 ? _collection[ existingMod.Index ].Settings!.Priority : existingMod.Priority;
|
||||
|
||||
if( existingPriority < addedPriority )
|
||||
{
|
||||
|
|
@ -417,7 +420,7 @@ public partial class ModCollection
|
|||
// For different mods, higher mod priority takes precedence before option group priority,
|
||||
// which takes precedence before option priority, which takes precedence before ordering.
|
||||
// Inside the same mod, conflicts are not recorded.
|
||||
private void AddManipulation( MetaManipulation manip, Mod mod )
|
||||
private void AddManipulation( MetaManipulation manip, IMod mod )
|
||||
{
|
||||
if( !MetaManipulations.TryGetValue( manip, out var existingMod ) )
|
||||
{
|
||||
|
|
@ -463,7 +466,7 @@ public partial class ModCollection
|
|||
{
|
||||
if( !_changedItems.TryGetValue( name, out var data ) )
|
||||
{
|
||||
_changedItems.Add( name, ( new SingleArray< Mod >( modPath.Mod ), obj ) );
|
||||
_changedItems.Add( name, ( new SingleArray< IMod >( modPath.Mod ), obj ) );
|
||||
}
|
||||
else if( !data.Item1.Contains( modPath.Mod ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public partial class MetaManager
|
|||
public struct MetaManagerCmp : IDisposable
|
||||
{
|
||||
public CmpFile? File = null;
|
||||
public readonly Dictionary< RspManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< RspManipulation, IMod > Manipulations = new();
|
||||
|
||||
public MetaManagerCmp()
|
||||
{ }
|
||||
|
|
@ -39,7 +39,7 @@ public partial class MetaManager
|
|||
Manipulations.Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod( RspManipulation m, Mod mod )
|
||||
public bool ApplyMod( RspManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_CMP
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public partial class MetaManager
|
|||
{
|
||||
public readonly ExpandedEqdpFile?[] Files = new ExpandedEqdpFile?[CharacterUtility.NumEqdpFiles - 2]; // TODO: female Hrothgar
|
||||
|
||||
public readonly Dictionary< EqdpManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< EqdpManipulation, IMod > Manipulations = new();
|
||||
|
||||
public MetaManagerEqdp()
|
||||
{ }
|
||||
|
|
@ -51,7 +51,7 @@ public partial class MetaManager
|
|||
Manipulations.Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod( EqdpManipulation m, Mod mod )
|
||||
public bool ApplyMod( EqdpManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_EQDP
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public partial class MetaManager
|
|||
public struct MetaManagerEqp : IDisposable
|
||||
{
|
||||
public ExpandedEqpFile? File = null;
|
||||
public readonly Dictionary< EqpManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< EqpManipulation, IMod > Manipulations = new();
|
||||
|
||||
public MetaManagerEqp()
|
||||
{ }
|
||||
|
|
@ -39,7 +39,7 @@ public partial class MetaManager
|
|||
Manipulations.Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod( EqpManipulation m, Mod mod )
|
||||
public bool ApplyMod( EqpManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_EQP
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public partial class MetaManager
|
|||
public EstFile? BodyFile = null;
|
||||
public EstFile? HeadFile = null;
|
||||
|
||||
public readonly Dictionary< EstManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< EstManipulation, IMod > Manipulations = new();
|
||||
|
||||
public MetaManagerEst()
|
||||
{ }
|
||||
|
|
@ -51,7 +51,7 @@ public partial class MetaManager
|
|||
Manipulations.Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod( EstManipulation m, Mod mod )
|
||||
public bool ApplyMod( EstManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_EST
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public partial class MetaManager
|
|||
public struct MetaManagerGmp : IDisposable
|
||||
{
|
||||
public ExpandedGmpFile? File = null;
|
||||
public readonly Dictionary< GmpManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< GmpManipulation, IMod > Manipulations = new();
|
||||
|
||||
public MetaManagerGmp()
|
||||
{ }
|
||||
|
|
@ -38,7 +38,7 @@ public partial class MetaManager
|
|||
}
|
||||
}
|
||||
|
||||
public bool ApplyMod( GmpManipulation m, Mod mod )
|
||||
public bool ApplyMod( GmpManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_GMP
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public partial class MetaManager
|
|||
public readonly struct MetaManagerImc : IDisposable
|
||||
{
|
||||
public readonly Dictionary< Utf8GamePath, ImcFile > Files = new();
|
||||
public readonly Dictionary< ImcManipulation, Mod > Manipulations = new();
|
||||
public readonly Dictionary< ImcManipulation, IMod > Manipulations = new();
|
||||
|
||||
private readonly ModCollection _collection;
|
||||
private static int _imcManagerCount;
|
||||
|
|
@ -65,7 +65,7 @@ public partial class MetaManager
|
|||
Manipulations.Clear();
|
||||
}
|
||||
|
||||
public bool ApplyMod( ImcManipulation m, Mod mod )
|
||||
public bool ApplyMod( ImcManipulation m, IMod mod )
|
||||
{
|
||||
#if USE_IMC
|
||||
Manipulations[ m ] = mod;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public partial class MetaManager : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue( MetaManipulation manip, [NotNullWhen(true)] out Mod? mod )
|
||||
public bool TryGetValue( MetaManipulation manip, [NotNullWhen(true)] out IMod? mod )
|
||||
{
|
||||
mod = manip.ManipulationType switch
|
||||
{
|
||||
|
|
@ -86,7 +86,7 @@ public partial class MetaManager : IDisposable
|
|||
Imc.Dispose();
|
||||
}
|
||||
|
||||
public bool ApplyMod( MetaManipulation m, Mod mod )
|
||||
public bool ApplyMod( MetaManipulation m, IMod mod )
|
||||
{
|
||||
return m.ManipulationType switch
|
||||
{
|
||||
|
|
|
|||
19
Penumbra/Mods/Editor/IMod.cs
Normal file
19
Penumbra/Mods/Editor/IMod.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System.Collections.Generic;
|
||||
using OtterGui.Classes;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public interface IMod
|
||||
{
|
||||
LowerString Name { get; }
|
||||
|
||||
public int Index { get; }
|
||||
public int Priority { get; }
|
||||
|
||||
public int TotalManipulations { get; }
|
||||
|
||||
public ISubMod Default { get; }
|
||||
public IReadOnlyList< IModGroup > Groups { get; }
|
||||
|
||||
public IEnumerable< ISubMod > AllSubMods { get; }
|
||||
}
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public partial class Mod
|
||||
public partial class Mod : IMod
|
||||
{
|
||||
public partial class Editor : IDisposable
|
||||
{
|
||||
|
|
@ -15,7 +12,7 @@ public partial class Mod
|
|||
|
||||
public Editor( Mod mod, int groupIdx, int optionIdx )
|
||||
{
|
||||
_mod = mod;
|
||||
_mod = mod;
|
||||
SetSubMod( groupIdx, optionIdx );
|
||||
GroupIdx = groupIdx;
|
||||
_subMod = _mod._default;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@ public partial class Mod
|
|||
public DirectoryInfo ModPath { get; private set; }
|
||||
public int Index { get; private set; } = -1;
|
||||
|
||||
// Unused if Index < 0 but used for special temporary mods.
|
||||
public int Priority
|
||||
=> 0;
|
||||
|
||||
private Mod( DirectoryInfo modPath )
|
||||
=> ModPath = modPath;
|
||||
|
||||
|
|
@ -30,7 +34,7 @@ public partial class Mod
|
|||
}
|
||||
|
||||
var mod = new Mod( modPath );
|
||||
if( !mod.Reload(out _) )
|
||||
if( !mod.Reload( out _ ) )
|
||||
{
|
||||
// Can not be base path not existing because that is checked before.
|
||||
PluginLog.Error( $"Mod at {modPath} without name is not supported." );
|
||||
|
|
@ -40,15 +44,17 @@ public partial class Mod
|
|||
return mod;
|
||||
}
|
||||
|
||||
private bool Reload(out MetaChangeType metaChange)
|
||||
private bool Reload( out MetaChangeType metaChange )
|
||||
{
|
||||
metaChange = MetaChangeType.Deletion;
|
||||
ModPath.Refresh();
|
||||
if( !ModPath.Exists )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
metaChange = LoadMeta();
|
||||
if( metaChange.HasFlag(MetaChangeType.Deletion) || Name.Length == 0 )
|
||||
if( metaChange.HasFlag( MetaChangeType.Deletion ) || Name.Length == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ public enum MetaChangeType : ushort
|
|||
|
||||
public sealed partial class Mod
|
||||
{
|
||||
public static readonly Mod ForcedFiles = new(new DirectoryInfo( "." ))
|
||||
public static readonly TemporaryMod ForcedFiles = new()
|
||||
{
|
||||
Name = "Forced Files",
|
||||
Index = -1,
|
||||
Name = "Forced Files",
|
||||
Index = -1,
|
||||
Priority = int.MaxValue,
|
||||
};
|
||||
|
||||
public const uint CurrentFileVersion = 1;
|
||||
|
|
|
|||
26
Penumbra/Mods/Mod.TemporaryMod.cs
Normal file
26
Penumbra/Mods/Mod.TemporaryMod.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OtterGui.Classes;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public sealed partial class Mod
|
||||
{
|
||||
public class TemporaryMod : IMod
|
||||
{
|
||||
public LowerString Name { get; init; } = LowerString.Empty;
|
||||
public int Index { get; init; } = -2;
|
||||
public int Priority { get; init; } = int.MaxValue;
|
||||
|
||||
public int TotalManipulations
|
||||
=> Default.Manipulations.Count;
|
||||
|
||||
public ISubMod Default { get; } = new SubMod();
|
||||
|
||||
public IReadOnlyList< IModGroup > Groups
|
||||
=> Array.Empty< IModGroup >();
|
||||
|
||||
public IEnumerable< ISubMod > AllSubMods
|
||||
=> new[] { Default };
|
||||
}
|
||||
}
|
||||
|
|
@ -23,13 +23,13 @@ public partial class ConfigWindow
|
|||
private void DrawChangedItemTab()
|
||||
{
|
||||
// Functions in here for less pollution.
|
||||
bool FilterChangedItem( KeyValuePair< string, (SingleArray< Mod >, object?) > item )
|
||||
bool FilterChangedItem( KeyValuePair< string, (SingleArray< IMod >, object?) > item )
|
||||
=> ( _changedItemFilter.IsEmpty
|
||||
|| ChangedItemName( item.Key, item.Value.Item2 )
|
||||
.Contains( _changedItemFilter.Lower, StringComparison.InvariantCultureIgnoreCase ) )
|
||||
&& ( _changedItemModFilter.IsEmpty || item.Value.Item1.Any( m => m.Name.Contains( _changedItemModFilter ) ) );
|
||||
|
||||
void DrawChangedItemColumn( KeyValuePair< string, (SingleArray< Mod >, object?) > item )
|
||||
void DrawChangedItemColumn( KeyValuePair< string, (SingleArray< IMod >, object?) > item )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
DrawChangedItem( item.Key, item.Value.Item2, false );
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public partial class ConfigWindow
|
|||
{
|
||||
// We can treat all meta manipulations the same,
|
||||
// we are only really interested in their ToString function here.
|
||||
static (object, Mod) Convert< T >( KeyValuePair< T, Mod > kvp )
|
||||
static (object, IMod) Convert< T >( KeyValuePair< T, IMod > kvp )
|
||||
=> ( kvp.Key!, kvp.Value );
|
||||
|
||||
var it = m.Cmp.Manipulations.Select( Convert )
|
||||
|
|
@ -183,7 +183,7 @@ public partial class ConfigWindow
|
|||
}
|
||||
|
||||
// Draw a line for a unfiltered/unconverted manipulation and mod-index pair.
|
||||
private static void DrawLine( (object, Mod) pair )
|
||||
private static void DrawLine( (object, IMod) pair )
|
||||
{
|
||||
var (manipulation, mod) = pair;
|
||||
ImGui.TableNextColumn();
|
||||
|
|
|
|||
|
|
@ -128,16 +128,19 @@ public partial class ConfigWindow
|
|||
|
||||
foreach( var conflict in Penumbra.CollectionManager.Current.Conflicts( _mod ) )
|
||||
{
|
||||
if( ImGui.Selectable( conflict.Mod2.Name ) )
|
||||
if( ImGui.Selectable( conflict.Mod2.Name ) && conflict.Mod2 is Mod mod )
|
||||
{
|
||||
_window._selector.SelectByValue( conflict.Mod2 );
|
||||
_window._selector.SelectByValue( mod );
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
using( var color = ImRaii.PushColor( ImGuiCol.Text,
|
||||
conflict.HasPriority ? ColorId.HandledConflictMod.Value() : ColorId.ConflictingMod.Value() ) )
|
||||
{
|
||||
ImGui.TextUnformatted( $"(Priority {Penumbra.CollectionManager.Current[ conflict.Mod2.Index ].Settings!.Priority})" );
|
||||
var priority = conflict.Mod2.Index < 0
|
||||
? conflict.Mod2.Priority
|
||||
: Penumbra.CollectionManager.Current[conflict.Mod2.Index].Settings!.Priority;
|
||||
ImGui.TextUnformatted( $"(Priority {priority})" );
|
||||
}
|
||||
|
||||
using var indent = ImRaii.PushIndent( 30f );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue