mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add changelog, improve Support Info, fix bug with folder checking, remove obsolete ownership settings.
This commit is contained in:
parent
893e0a13bd
commit
c8edd87df8
6 changed files with 99 additions and 70 deletions
|
|
@ -170,7 +170,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
// Wrappers around Individual Collection handling.
|
||||
public void CreateIndividualCollection( ActorIdentifier[] identifiers )
|
||||
public void CreateIndividualCollection( params ActorIdentifier[] identifiers )
|
||||
{
|
||||
if( Individuals.Add( identifiers, Default ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ public partial class Configuration : IPluginConfiguration
|
|||
public bool UseCharacterCollectionInInspect { get; set; } = true;
|
||||
public bool UseCharacterCollectionInTryOn { get; set; } = true;
|
||||
public bool UseOwnerNameForCharacterCollection { get; set; } = true;
|
||||
public bool PreferNamedCollectionsOverOwners { get; set; } = true;
|
||||
public bool UseDefaultCollectionForRetainers { get; set; } = false;
|
||||
|
||||
public bool HideRedrawBar { get; set; } = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ using Penumbra.GameData.Actors;
|
|||
using Penumbra.Interop.Loader;
|
||||
using Penumbra.Interop.Resolver;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.String;
|
||||
using CharacterUtility = Penumbra.Interop.CharacterUtility;
|
||||
using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager;
|
||||
|
||||
|
|
@ -337,7 +338,7 @@ public class Penumbra : IDalamudPlugin
|
|||
var split = collectionName.Split( '|', 2, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries );
|
||||
if( split.Length < 2 || split[ 0 ].Length == 0 || split[ 1 ].Length == 0 )
|
||||
{
|
||||
Dalamud.Chat.Print( "You need to provide a collection and a character name in the form of 'collection | character' to set a character collection." );
|
||||
Dalamud.Chat.Print( "You need to provide a collection and a character name in the form of 'collection | name' to set an individual collection." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -355,27 +356,33 @@ public class Penumbra : IDalamudPlugin
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO
|
||||
//var oldCollection = CollectionManager.ByType( type, characterName );
|
||||
//if( collection == oldCollection )
|
||||
//{
|
||||
// Dalamud.Chat.Print( $"{collection.Name} already is the {type.ToName()} Collection." );
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//if( oldCollection == null )
|
||||
//{
|
||||
// if( type.IsSpecial() )
|
||||
// {
|
||||
// CollectionManager.CreateSpecialCollection( type );
|
||||
// }
|
||||
// else if( type is CollectionType.Individual )
|
||||
// {
|
||||
// CollectionManager.CreateIndividualCollection( characterName! );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//CollectionManager.SetCollection( collection, type, characterName );
|
||||
var identifier = Actors.CreatePlayer( ByteString.FromStringUnsafe( characterName, false ), ushort.MaxValue );
|
||||
if( !identifier.IsValid )
|
||||
{
|
||||
Dalamud.Chat.Print( $"{characterName} is not a valid character name." );
|
||||
return false;
|
||||
}
|
||||
|
||||
var oldCollection = CollectionManager.ByType( type, identifier );
|
||||
if( collection == oldCollection )
|
||||
{
|
||||
Dalamud.Chat.Print( $"{collection.Name} already is the {type.ToName()} Collection." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( oldCollection == null )
|
||||
{
|
||||
if( type.IsSpecial() )
|
||||
{
|
||||
CollectionManager.CreateSpecialCollection( type );
|
||||
}
|
||||
else if( type is CollectionType.Individual )
|
||||
{
|
||||
CollectionManager.CreateIndividualCollection( identifier );
|
||||
}
|
||||
}
|
||||
|
||||
CollectionManager.SetCollection( collection, type, CollectionManager.Individuals.Count - 1 );
|
||||
Dalamud.Chat.Print( $"Set {collection.Name} as {type.ToName()} Collection{( characterName != null ? $" for {characterName}." : "." )}" );
|
||||
return true;
|
||||
}
|
||||
|
|
@ -490,62 +497,61 @@ public class Penumbra : IDalamudPlugin
|
|||
var exists = Config.ModDirectory.Length > 0 && Directory.Exists( Config.ModDirectory );
|
||||
var drive = exists ? new DriveInfo( new DirectoryInfo( Config.ModDirectory ).Root.FullName ) : null;
|
||||
sb.AppendLine( "**Settings**" );
|
||||
sb.AppendFormat( "> **`Plugin Version: `** {0}\n", Version );
|
||||
sb.AppendFormat( "> **`Commit Hash: `** {0}\n", CommitHash );
|
||||
sb.AppendFormat( "> **`Enable Mods: `** {0}\n", Config.EnableMods );
|
||||
sb.AppendFormat( "> **`Enable HTTP API: `** {0}\n", Config.EnableHttpApi );
|
||||
sb.AppendFormat( "> **`Root Directory: `** `{0}`, {1}\n", Config.ModDirectory, exists ? "Exists" : "Not Existing" );
|
||||
sb.AppendFormat( "> **`Free Drive Space: `** {0}\n",
|
||||
drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" );
|
||||
sb.Append( $"> **`Plugin Version: `** {Version}\n" );
|
||||
sb.Append( $"> **`Commit Hash: `** {CommitHash}\n" );
|
||||
sb.Append( $"> **`Enable Mods: `** {Config.EnableMods}\n" );
|
||||
sb.Append( $"> **`Enable HTTP API: `** {Config.EnableHttpApi}\n" );
|
||||
sb.Append( $"> **`Root Directory: `** `{Config.ModDirectory}`, {( exists ? "Exists" : "Not Existing" )}\n" );
|
||||
sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" );
|
||||
sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" );
|
||||
sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" );
|
||||
sb.Append( $"> **`Logging: `** Full: {Config.EnableFullResourceLogging}, Resource: {Config.EnableResourceLogging}\n" );
|
||||
sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" );
|
||||
sb.AppendLine( "**Mods**" );
|
||||
sb.AppendFormat( "> **`Installed Mods: `** {0}\n", ModManager.Count );
|
||||
sb.AppendFormat( "> **`Mods with Config: `** {0}\n", ModManager.Count( m => m.HasOptions ) );
|
||||
sb.AppendFormat( "> **`Mods with File Redirections: `** {0}, Total: {1}\n", ModManager.Count( m => m.TotalFileCount > 0 ),
|
||||
ModManager.Sum( m => m.TotalFileCount ) );
|
||||
sb.AppendFormat( "> **`Mods with FileSwaps: `** {0}, Total: {1}\n", ModManager.Count( m => m.TotalSwapCount > 0 ),
|
||||
ModManager.Sum( m => m.TotalSwapCount ) );
|
||||
sb.AppendFormat( "> **`Mods with Meta Manipulations:`** {0}, Total {1}\n", ModManager.Count( m => m.TotalManipulations > 0 ),
|
||||
ModManager.Sum( m => m.TotalManipulations ) );
|
||||
sb.AppendFormat( "> **`IMC Exceptions Thrown: `** {0}\n", ImcExceptions );
|
||||
sb.Append( $"> **`Installed Mods: `** {ModManager.Count}\n" );
|
||||
sb.Append( $"> **`Mods with Config: `** {ModManager.Count( m => m.HasOptions )}\n" );
|
||||
sb.Append( $"> **`Mods with File Redirections: `** {ModManager.Count( m => m.TotalFileCount > 0 )}, Total: {ModManager.Sum( m => m.TotalFileCount )}\n" );
|
||||
sb.Append( $"> **`Mods with FileSwaps: `** {ModManager.Count( m => m.TotalSwapCount > 0 )}, Total: {ModManager.Sum( m => m.TotalSwapCount )}\n" );
|
||||
sb.Append( $"> **`Mods with Meta Manipulations:`** {ModManager.Count( m => m.TotalManipulations > 0 )}, Total {ModManager.Sum( m => m.TotalManipulations )}\n" );
|
||||
sb.Append( $"> **`IMC Exceptions Thrown: `** {ImcExceptions.Count}\n" );
|
||||
sb.Append( $"> **`#Temp Mods: `** {TempMods.Mods.Sum( kvp => kvp.Value.Count ) + TempMods.ModsForAllCollections.Count}\n" );
|
||||
|
||||
string CharacterName( ActorIdentifier id, string name )
|
||||
{
|
||||
if( id.Type is IdentifierType.Player or IdentifierType.Owned )
|
||||
{
|
||||
return string.Join( " ", name.Split( ' ', 3 ).Select( n => $"{n[ 0 ]}." ) ) + ':';
|
||||
var parts = name.Split( ' ', 3 );
|
||||
return string.Join( " ", parts.Length != 3 ? parts.Select( n => $"{n[ 0 ]}." ) : parts[ ..2 ].Select( n => $"{n[ 0 ]}." ).Append( parts[2] ) );
|
||||
}
|
||||
|
||||
return name + ':';
|
||||
}
|
||||
|
||||
void PrintCollection( ModCollection c )
|
||||
=> sb.AppendFormat( "**Collection {0}**\n"
|
||||
+ "> **`Inheritances: `** {1}\n"
|
||||
+ "> **`Enabled Mods: `** {2}\n"
|
||||
+ "> **`Total Conflicts: `** {3}\n"
|
||||
+ "> **`Solved Conflicts: `** {4}\n",
|
||||
c.AnonymizedName, c.Inheritance.Count, c.ActualSettings.Count( s => s is { Enabled: true } ),
|
||||
c.AllConflicts.SelectMany( x => x ).Sum( x => x.HasPriority ? 0 : x.Conflicts.Count ),
|
||||
c.AllConflicts.SelectMany( x => x ).Sum( x => x.HasPriority || !x.Solved ? 0 : x.Conflicts.Count ) );
|
||||
=> sb.Append( $"**Collection {c.AnonymizedName}**\n"
|
||||
+ $"> **`Inheritances: `** {c.Inheritance.Count}\n"
|
||||
+ $"> **`Enabled Mods: `** {c.ActualSettings.Count( s => s is { Enabled: true } )}\n"
|
||||
+ $"> **`Conflicts (Solved/Total): `** {c.AllConflicts.SelectMany( x => x ).Sum( x => x.HasPriority ? 0 : x.Conflicts.Count )}/{c.AllConflicts.SelectMany( x => x ).Sum( x => x.HasPriority || !x.Solved ? 0 : x.Conflicts.Count )}\n" );
|
||||
|
||||
sb.AppendLine( "**Collections**" );
|
||||
sb.AppendFormat( "> **`#Collections: `** {0}\n", CollectionManager.Count - 1 );
|
||||
sb.AppendFormat( "> **`Active Collections: `** {0}\n", CollectionManager.Count( c => c.HasCache ) );
|
||||
sb.AppendFormat( "> **`Base Collection: `** {0}\n", CollectionManager.Default.AnonymizedName );
|
||||
sb.AppendFormat( "> **`Interface Collection: `** {0}\n", CollectionManager.Interface.AnonymizedName );
|
||||
sb.AppendFormat( "> **`Selected Collection: `** {0}\n", CollectionManager.Current.AnonymizedName );
|
||||
sb.Append( $"> **`#Collections: `** {CollectionManager.Count - 1}\n" );
|
||||
sb.Append( $"> **`#Temp Collections: `** {TempMods.CustomCollections.Count}\n" );
|
||||
sb.Append( $"> **`Active Collections: `** {CollectionManager.Count( c => c.HasCache )}\n" );
|
||||
sb.Append( $"> **`Base Collection: `** {CollectionManager.Default.AnonymizedName}\n" );
|
||||
sb.Append( $"> **`Interface Collection: `** {CollectionManager.Interface.AnonymizedName}\n" );
|
||||
sb.Append( $"> **`Selected Collection: `** {CollectionManager.Current.AnonymizedName}\n" );
|
||||
foreach( var (type, name, _) in CollectionTypeExtensions.Special )
|
||||
{
|
||||
var collection = CollectionManager.ByType( type );
|
||||
if( collection != null )
|
||||
{
|
||||
sb.AppendFormat( "> **`{0,-29}`** {1}\n", name, collection.AnonymizedName );
|
||||
sb.Append( $"> **`{name,-30}`** {collection.AnonymizedName}\n" );
|
||||
}
|
||||
}
|
||||
|
||||
foreach( var (name, id, collection) in CollectionManager.Individuals.Assignments )
|
||||
{
|
||||
sb.AppendFormat( "> **`{1,-29}`** {0}\n", collection.AnonymizedName, CharacterName( id[ 0 ], name ) );
|
||||
sb.Append( $"> **`{CharacterName( id[ 0 ], name ),-30}`** {collection.AnonymizedName}\n" );
|
||||
}
|
||||
|
||||
foreach( var collection in CollectionManager.Where( c => c.HasCache ) )
|
||||
|
|
|
|||
|
|
@ -24,10 +24,38 @@ public partial class ConfigWindow
|
|||
Add5_10_0( ret );
|
||||
Add5_11_0( ret );
|
||||
Add5_11_1( ret );
|
||||
Add6_0_0( ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static void Add6_0_0( Changelog log )
|
||||
=> log.NextVersion( "Version 0.6.0.0" )
|
||||
.RegisterEntry( "Revamped Individual Collections:" )
|
||||
.RegisterEntry( "You can now specify individual collections for players (by name) of specific worlds or any world.", 1 )
|
||||
.RegisterEntry( "You can also specify NPCs (by grouped name and type of NPC), and owned NPCs (by specifying an NPC and a Player).", 1 )
|
||||
.RegisterHighlight(
|
||||
"Migration should move all current names that correspond to NPCs to the appropriate NPC group and all names that can be valid Player names to a Player of any world.",
|
||||
1 )
|
||||
.RegisterHighlight(
|
||||
"Please look through your Individual Collections to verify everything migrated correctly and corresponds to the game object you want. You might also want to change the 'Player (Any World)' collections to your specific homeworld.",
|
||||
1 )
|
||||
.RegisterEntry( "You can also manually sort your Individual Collections by drag and drop now.", 1 )
|
||||
.RegisterEntry( "This new system is a pretty big rework, so please report any discrepancies or bugs you find.", 1 )
|
||||
.RegisterEntry( "These changes made the specific ownership settings for Retainers and for preferring named over ownership obsolete.", 1 )
|
||||
.RegisterEntry( "General ownership can still be toggled and should apply in order of: Owned NPC > Owner (if enabled) > General NPC.", 1 )
|
||||
.RegisterEntry( "Added Dye Previews for in-game dyes and dyeing templates in Material Editing." )
|
||||
.RegisterEntry( "Added Export buttons to .mdl and .mtrl previews in Advanced Editing." )
|
||||
.RegisterEntry( "Collection selectors can now be filtered by name." )
|
||||
.RegisterEntry( "Try to use Unicode normalization before replacing invalid path symbols on import for somewhat nicer paths." )
|
||||
.RegisterEntry( "Improved interface for group settings (minimally)." )
|
||||
.RegisterEntry( "Prevent a bug that allowed IPC to add Mods from outside the Penumbra root folder." )
|
||||
.RegisterEntry( "Improved Support Info somewhat." )
|
||||
.RegisterEntry( "Fixed a bug when dragging options during mod edit." )
|
||||
.RegisterEntry( "Fixed a bug where sometimes the valid folder check caused issues." )
|
||||
.RegisterEntry( "Fixed a bug where the /penumbra enable/disable command displayed the wrong message (functionality unchanged)." )
|
||||
.RegisterEntry( "A lot of big backend changes." );
|
||||
|
||||
private static void Add5_11_1( Changelog log )
|
||||
=> log.NextVersion( "Version 0.5.11.1" )
|
||||
.RegisterEntry(
|
||||
|
|
|
|||
|
|
@ -63,28 +63,20 @@ public partial class ConfigWindow
|
|||
Penumbra.Config.HideRedrawBar, v => Penumbra.Config.HideRedrawBar = v );
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
Checkbox( $"Use {AssignedCollections} in Character Window",
|
||||
"Use the character collection for your characters name or the Your Character collection in your main character window, if it is set.",
|
||||
"Use the individual collection for your characters name or the Your Character collection in your main character window, if it is set.",
|
||||
Penumbra.Config.UseCharacterCollectionInMainWindow, v => Penumbra.Config.UseCharacterCollectionInMainWindow = v );
|
||||
Checkbox( $"Use {AssignedCollections} in Adventurer Cards",
|
||||
"Use the appropriate character collection for the adventurer card you are currently looking at, based on the adventurer's name.",
|
||||
"Use the appropriate individual collection for the adventurer card you are currently looking at, based on the adventurer's name.",
|
||||
Penumbra.Config.UseCharacterCollectionsInCards, v => Penumbra.Config.UseCharacterCollectionsInCards = v );
|
||||
Checkbox( $"Use {AssignedCollections} in Try-On Window",
|
||||
"Use the character collection for your character's name in your try-on, dye preview or glamour plate window, if it is set.",
|
||||
"Use the individual collection for your character's name in your try-on, dye preview or glamour plate window, if it is set.",
|
||||
Penumbra.Config.UseCharacterCollectionInTryOn, v => Penumbra.Config.UseCharacterCollectionInTryOn = v );
|
||||
Checkbox( $"Use {AssignedCollections} in Inspect Windows",
|
||||
"Use the appropriate character collection for the character you are currently inspecting, based on their name.",
|
||||
"Use the appropriate individual collection for the character you are currently inspecting, based on their name.",
|
||||
Penumbra.Config.UseCharacterCollectionInInspect, v => Penumbra.Config.UseCharacterCollectionInInspect = v );
|
||||
Checkbox( $"Use {AssignedCollections} based on Ownership",
|
||||
"Use the owner's name to determine the appropriate character collection for mounts, companions and combat pets.",
|
||||
"Use the owner's name to determine the appropriate individual collection for mounts, companions, accessories and combat pets.",
|
||||
Penumbra.Config.UseOwnerNameForCharacterCollection, v => Penumbra.Config.UseOwnerNameForCharacterCollection = v );
|
||||
Checkbox( "Prefer Named Collections over Ownership",
|
||||
"If you have a character collection set to a specific name for a companion or combat pet, prefer this collection over the owners collection.\n"
|
||||
+ "That is, if you have a 'Topaz Carbuncle' collection, it will use this one instead of the one for its owner.",
|
||||
Penumbra.Config.PreferNamedCollectionsOverOwners, v => Penumbra.Config.PreferNamedCollectionsOverOwners = v );
|
||||
Checkbox( $"Use {DefaultCollection} for Housing Retainers",
|
||||
$"Housing Retainers use the name of their owner instead of their own, you can decide to let them use their owners character collection or the {DefaultCollection}.\n"
|
||||
+ "It is not possible to make them have their own collection, since they have no connection to their actual name.",
|
||||
Penumbra.Config.UseDefaultCollectionForRetainers, v => Penumbra.Config.UseDefaultCollectionForRetainers = v );
|
||||
ImGui.Dummy( _window._defaultSpace );
|
||||
DrawFolderSortType();
|
||||
DrawAbsoluteSizeSelector();
|
||||
|
|
|
|||
|
|
@ -85,6 +85,11 @@ public partial class ConfigWindow
|
|||
{
|
||||
static bool IsSubPathOf( string basePath, string subPath )
|
||||
{
|
||||
if( basePath.Length == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var rel = Path.GetRelativePath( basePath, subPath );
|
||||
return rel == "." || !rel.StartsWith( '.' ) && !Path.IsPathRooted( rel );
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue