diff --git a/Penumbra.Api/IPenumbraApi.cs b/Penumbra.Api/IPenumbraApi.cs index cdfa75c9..a77b4347 100644 --- a/Penumbra.Api/IPenumbraApi.cs +++ b/Penumbra.Api/IPenumbraApi.cs @@ -1,4 +1,3 @@ -using System; using Dalamud.Game.ClientState.Actors.Types; namespace Penumbra.Api diff --git a/Penumbra.GameData/Enums/RspAttribute.cs b/Penumbra.GameData/Enums/RspAttribute.cs index c78ecf53..07d03b67 100644 --- a/Penumbra.GameData/Enums/RspAttribute.cs +++ b/Penumbra.GameData/Enums/RspAttribute.cs @@ -1,3 +1,5 @@ +using System.ComponentModel; + namespace Penumbra.GameData.Enums { public enum RspAttribute : byte @@ -64,5 +66,27 @@ namespace Penumbra.GameData.Enums _ => "", }; } + + public static string ToFullString( this RspAttribute attribute ) + { + return attribute switch + { + RspAttribute.MaleMinSize => "Male Minimum Size", + RspAttribute.MaleMaxSize => "Male Maximum Size", + RspAttribute.FemaleMinSize => "Female Minimum Size", + RspAttribute.FemaleMaxSize => "Female Maximum Size", + RspAttribute.BustMinX => "Bust Minimum X-Axis", + RspAttribute.BustMaxX => "Bust Maximum X-Axis", + RspAttribute.BustMinY => "Bust Minimum Y-Axis", + RspAttribute.BustMaxY => "Bust Maximum Y-Axis", + RspAttribute.BustMinZ => "Bust Minimum Z-Axis", + RspAttribute.BustMaxZ => "Bust Maximum Z-Axis", + RspAttribute.MaleMinTail => "Male Minimum Tail Length", + RspAttribute.MaleMaxTail => "Male Maximum Tail Length", + RspAttribute.FemaleMinTail => "Female Minimum Tail Length", + RspAttribute.FemaleMaxTail => "Female Maximum Tail Length", + _ => throw new InvalidEnumArgumentException(), + }; + } } } \ No newline at end of file diff --git a/Penumbra.GameData/GameData.cs b/Penumbra.GameData/GameData.cs index 1c3670f8..d3800a6e 100644 --- a/Penumbra.GameData/GameData.cs +++ b/Penumbra.GameData/GameData.cs @@ -19,12 +19,13 @@ namespace Penumbra.GameData return Identification; } - public static IObjectIdentifier GetIdentifier( ) + public static IObjectIdentifier GetIdentifier() { if( Identification == null ) { throw new Exception( "Object Identification was not initialized." ); } + return Identification; } diff --git a/Penumbra.GameData/GamePathParser.cs b/Penumbra.GameData/GamePathParser.cs index 3a979edf..0b456ba4 100644 --- a/Penumbra.GameData/GamePathParser.cs +++ b/Penumbra.GameData/GamePathParser.cs @@ -122,7 +122,7 @@ namespace Penumbra.GameData private (FileType, ObjectType, Match?) ParseGamePath( GamePath path ) { - if( !Enums.Names.ExtensionToFileType.TryGetValue( Extension( path ), out var fileType ) ) + if( !Names.ExtensionToFileType.TryGetValue( Extension( path ), out var fileType ) ) { fileType = FileType.Unknown; } @@ -165,8 +165,8 @@ namespace Penumbra.GameData return GameObjectInfo.Equipment( fileType, setId ); } - var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value ); - var slot = Enums.Names.SuffixToEquipSlot[ groups[ "slot" ].Value ]; + var gr = Names.GenderRaceFromCode( groups[ "race" ].Value ); + var slot = Names.SuffixToEquipSlot[ groups[ "slot" ].Value ]; if( fileType == FileType.Model ) { return GameObjectInfo.Equipment( fileType, setId, gr, slot ); @@ -211,7 +211,7 @@ namespace Penumbra.GameData return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId ); } - var slot = Enums.Names.SuffixToEquipSlot[ groups[ "slot" ].Value ]; + var slot = Names.SuffixToEquipSlot[ groups[ "slot" ].Value ]; if( fileType == FileType.Model ) { return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot ); @@ -236,10 +236,10 @@ namespace Penumbra.GameData return GameObjectInfo.Customization( fileType, tmpType, id ); } - var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value ); - var bodySlot = Enums.Names.StringToBodySlot[ groups[ "type" ].Value ]; + var gr = Names.GenderRaceFromCode( groups[ "race" ].Value ); + var bodySlot = Names.StringToBodySlot[ groups[ "type" ].Value ]; var type = groups[ "slot" ].Success - ? Enums.Names.SuffixToCustomizationType[ groups[ "slot" ].Value ] + ? Names.SuffixToCustomizationType[ groups[ "slot" ].Value ] : CustomizationType.Skin; if( fileType == FileType.Material ) { diff --git a/Penumbra.GameData/Structs/ActorEquip.cs b/Penumbra.GameData/Structs/ActorEquip.cs index 8aa63708..646067d0 100644 --- a/Penumbra.GameData/Structs/ActorEquip.cs +++ b/Penumbra.GameData/Structs/ActorEquip.cs @@ -24,4 +24,4 @@ namespace Penumbra.GameData.Structs public override string ToString() => $"{Set},{Type},{Variant},{Stain}"; } -} +} \ No newline at end of file diff --git a/Penumbra.GameData/Structs/EqpEntry.cs b/Penumbra.GameData/Structs/EqpEntry.cs index 5794a905..2e4c0d86 100644 --- a/Penumbra.GameData/Structs/EqpEntry.cs +++ b/Penumbra.GameData/Structs/EqpEntry.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.ComponentModel; using Penumbra.GameData.Enums; @@ -126,5 +128,181 @@ namespace Penumbra.GameData.Structs _ => 0, }; } + + public static EquipSlot ToEquipSlot( this EqpEntry entry ) + { + return entry switch + { + EqpEntry.BodyEnabled => EquipSlot.Body, + EqpEntry.BodyHideWaist => EquipSlot.Body, + EqpEntry._2 => EquipSlot.Body, + EqpEntry.BodyHideGlovesS => EquipSlot.Body, + EqpEntry._4 => EquipSlot.Body, + EqpEntry.BodyHideGlovesM => EquipSlot.Body, + EqpEntry.BodyHideGlovesL => EquipSlot.Body, + EqpEntry.BodyHideGorget => EquipSlot.Body, + EqpEntry.BodyShowLeg => EquipSlot.Body, + EqpEntry.BodyShowHand => EquipSlot.Body, + EqpEntry.BodyShowHead => EquipSlot.Body, + EqpEntry.BodyShowNecklace => EquipSlot.Body, + EqpEntry.BodyShowBracelet => EquipSlot.Body, + EqpEntry.BodyShowTail => EquipSlot.Body, + EqpEntry._14 => EquipSlot.Body, + EqpEntry._15 => EquipSlot.Body, + + EqpEntry.LegsEnabled => EquipSlot.Legs, + EqpEntry.LegsHideKneePads => EquipSlot.Legs, + EqpEntry.LegsHideBootsS => EquipSlot.Legs, + EqpEntry.LegsHideBootsM => EquipSlot.Legs, + EqpEntry._20 => EquipSlot.Legs, + EqpEntry.LegsShowFoot => EquipSlot.Legs, + EqpEntry.LegsShowTail => EquipSlot.Legs, + EqpEntry._23 => EquipSlot.Legs, + + EqpEntry.HandsEnabled => EquipSlot.Hands, + EqpEntry.HandsHideElbow => EquipSlot.Hands, + EqpEntry.HandsHideForearm => EquipSlot.Hands, + EqpEntry._27 => EquipSlot.Hands, + EqpEntry.HandShowBracelet => EquipSlot.Hands, + EqpEntry.HandShowRingL => EquipSlot.Hands, + EqpEntry.HandShowRingR => EquipSlot.Hands, + EqpEntry._31 => EquipSlot.Hands, + + EqpEntry.FeetEnabled => EquipSlot.Feet, + EqpEntry.FeetHideKnee => EquipSlot.Feet, + EqpEntry.FeetHideCalf => EquipSlot.Feet, + EqpEntry.FeetHideAnkle => EquipSlot.Feet, + EqpEntry._36 => EquipSlot.Feet, + EqpEntry._37 => EquipSlot.Feet, + EqpEntry._38 => EquipSlot.Feet, + EqpEntry._39 => EquipSlot.Feet, + + EqpEntry.HeadEnabled => EquipSlot.Head, + EqpEntry.HeadHideScalp => EquipSlot.Head, + EqpEntry.HeadHideHair => EquipSlot.Head, + EqpEntry.HeadShowHairOverride => EquipSlot.Head, + EqpEntry.HeadHideNeck => EquipSlot.Head, + EqpEntry.HeadShowNecklace => EquipSlot.Head, + EqpEntry._46 => EquipSlot.Head, + EqpEntry.HeadShowEarrings => EquipSlot.Head, + EqpEntry.HeadShowEarringsHuman => EquipSlot.Head, + EqpEntry.HeadShowEarringsAura => EquipSlot.Head, + EqpEntry.HeadShowEarHuman => EquipSlot.Head, + EqpEntry.HeadShowEarMiqote => EquipSlot.Head, + EqpEntry.HeadShowEarAuRa => EquipSlot.Head, + EqpEntry.HeadShowEarViera => EquipSlot.Head, + EqpEntry._54 => EquipSlot.Head, + EqpEntry._55 => EquipSlot.Head, + EqpEntry.HeadShowHrothgarHat => EquipSlot.Head, + EqpEntry.HeadShowVieraHat => EquipSlot.Head, + EqpEntry._58 => EquipSlot.Head, + EqpEntry._59 => EquipSlot.Head, + EqpEntry._60 => EquipSlot.Head, + EqpEntry._61 => EquipSlot.Head, + EqpEntry._62 => EquipSlot.Head, + EqpEntry._63 => EquipSlot.Head, + + _ => EquipSlot.Unknown, + }; + } + + public static string ToLocalName( this EqpEntry entry ) + { + return entry switch + { + EqpEntry.BodyEnabled => "Enabled", + EqpEntry.BodyHideWaist => "Hide Waist", + EqpEntry._2 => "Unknown 2", + EqpEntry.BodyHideGlovesS => "Hide Small Gloves", + EqpEntry._4 => "Unknown 4", + EqpEntry.BodyHideGlovesM => "Hide Medium Gloves", + EqpEntry.BodyHideGlovesL => "Hide Large Gloves", + EqpEntry.BodyHideGorget => "Hide Gorget", + EqpEntry.BodyShowLeg => "Show Legs", + EqpEntry.BodyShowHand => "Show Hands", + EqpEntry.BodyShowHead => "Show Head", + EqpEntry.BodyShowNecklace => "Show Necklace", + EqpEntry.BodyShowBracelet => "Show Bracelet", + EqpEntry.BodyShowTail => "Show Tail", + EqpEntry._14 => "Unknown 14", + EqpEntry._15 => "Unknown 15", + + EqpEntry.LegsEnabled => "Enabled", + EqpEntry.LegsHideKneePads => "Hide Knee Pads", + EqpEntry.LegsHideBootsS => "Hide Small Boots", + EqpEntry.LegsHideBootsM => "Hide Medium Boots", + EqpEntry._20 => "Unknown 20", + EqpEntry.LegsShowFoot => "Show Foot", + EqpEntry.LegsShowTail => "Show Tail", + EqpEntry._23 => "Unknown 23", + + EqpEntry.HandsEnabled => "Enabled", + EqpEntry.HandsHideElbow => "Hide Elbow", + EqpEntry.HandsHideForearm => "Hide Forearm", + EqpEntry._27 => "Unknown 27", + EqpEntry.HandShowBracelet => "Show Bracelet", + EqpEntry.HandShowRingL => "Show Left Ring", + EqpEntry.HandShowRingR => "Show Right Ring", + EqpEntry._31 => "Unknown 31", + + EqpEntry.FeetEnabled => "Enabled", + EqpEntry.FeetHideKnee => "Hide Knees", + EqpEntry.FeetHideCalf => "Hide Calves", + EqpEntry.FeetHideAnkle => "Hide Ankles", + EqpEntry._36 => "Unknown 36", + EqpEntry._37 => "Unknown 37", + EqpEntry._38 => "Unknown 38", + EqpEntry._39 => "Unknown 39", + + EqpEntry.HeadEnabled => "Enabled", + EqpEntry.HeadHideScalp => "Hide Scalp", + EqpEntry.HeadHideHair => "Hide Hair", + EqpEntry.HeadShowHairOverride => "Show Hair Override", + EqpEntry.HeadHideNeck => "Hide Neck", + EqpEntry.HeadShowNecklace => "Show Necklace", + EqpEntry._46 => "Unknown 46", + EqpEntry.HeadShowEarrings => "Show Earrings", + EqpEntry.HeadShowEarringsHuman => "Show Earrings (Human)", + EqpEntry.HeadShowEarringsAura => "Show Earrings (Au Ra)", + EqpEntry.HeadShowEarHuman => "Show Ears (Human)", + EqpEntry.HeadShowEarMiqote => "Show Ears (Miqo'te)", + EqpEntry.HeadShowEarAuRa => "Show Ears (Au Ra)", + EqpEntry.HeadShowEarViera => "Show Ears (Viera)", + EqpEntry._54 => "Unknown 54", + EqpEntry._55 => "Unknown 55", + EqpEntry.HeadShowHrothgarHat => "Show on Hrothgar", + EqpEntry.HeadShowVieraHat => "Show on Viera", + EqpEntry._58 => "Unknown 58", + EqpEntry._59 => "Unknown 59", + EqpEntry._60 => "Unknown 60", + EqpEntry._61 => "Unknown 61", + EqpEntry._62 => "Unknown 62", + EqpEntry._63 => "Unknown 63", + + _ => throw new InvalidEnumArgumentException(), + }; + } + + private static EqpEntry[] GetEntriesForSlot( EquipSlot slot ) + { + return ( ( EqpEntry[] )Enum.GetValues( typeof( EqpEntry ) ) ) + .Where( e => e.ToEquipSlot() == slot ) + .ToArray(); + } + + public static readonly EqpEntry[] EqpAttributesBody = GetEntriesForSlot( EquipSlot.Body ); + public static readonly EqpEntry[] EqpAttributesLegs = GetEntriesForSlot( EquipSlot.Legs ); + public static readonly EqpEntry[] EqpAttributesHands = GetEntriesForSlot( EquipSlot.Hands ); + public static readonly EqpEntry[] EqpAttributesFeet = GetEntriesForSlot( EquipSlot.Feet ); + public static readonly EqpEntry[] EqpAttributesHead = GetEntriesForSlot( EquipSlot.Head ); + + public static IReadOnlyDictionary< EquipSlot, EqpEntry[] > EqpAttributes = new Dictionary< EquipSlot, EqpEntry[] >() + { + [ EquipSlot.Body ] = EqpAttributesBody, + [ EquipSlot.Legs ] = EqpAttributesLegs, + [ EquipSlot.Hands ] = EqpAttributesHands, + [ EquipSlot.Feet ] = EqpAttributesFeet, + [ EquipSlot.Head ] = EqpAttributesHead, + }; } } \ No newline at end of file diff --git a/Penumbra.GameData/Structs/SetId.cs b/Penumbra.GameData/Structs/SetId.cs index 58fbb913..a2483538 100644 --- a/Penumbra.GameData/Structs/SetId.cs +++ b/Penumbra.GameData/Structs/SetId.cs @@ -2,14 +2,15 @@ using System; namespace Penumbra.GameData.Structs { - public readonly struct SetId : IComparable + public readonly struct SetId : IComparable< SetId > { public readonly ushort Value; public SetId( ushort value ) => Value = value; - public static implicit operator SetId( ushort id ) => new(id); + public static implicit operator SetId( ushort id ) + => new( id ); public static explicit operator ushort( SetId id ) => id.Value; @@ -20,4 +21,4 @@ namespace Penumbra.GameData.Structs public int CompareTo( SetId other ) => Value.CompareTo( other.Value ); } -} +} \ No newline at end of file diff --git a/Penumbra.GameData/Structs/StainId.cs b/Penumbra.GameData/Structs/StainId.cs index 506066a4..74a479a1 100644 --- a/Penumbra.GameData/Structs/StainId.cs +++ b/Penumbra.GameData/Structs/StainId.cs @@ -2,14 +2,15 @@ using System; namespace Penumbra.GameData.Structs { - public readonly struct StainId : IEquatable + public readonly struct StainId : IEquatable< StainId > { public readonly byte Value; public StainId( byte value ) => Value = value; - public static implicit operator StainId( byte id ) => new( id ); + public static implicit operator StainId( byte id ) + => new( id ); public static explicit operator byte( StainId id ) => id.Value; @@ -26,4 +27,4 @@ namespace Penumbra.GameData.Structs public override int GetHashCode() => Value.GetHashCode(); } -} +} \ No newline at end of file diff --git a/Penumbra.GameData/Structs/WeaponType.cs b/Penumbra.GameData/Structs/WeaponType.cs index d0f99d8f..a5fa6107 100644 --- a/Penumbra.GameData/Structs/WeaponType.cs +++ b/Penumbra.GameData/Structs/WeaponType.cs @@ -2,14 +2,15 @@ using System; namespace Penumbra.GameData.Structs { - public readonly struct WeaponType : IEquatable + public readonly struct WeaponType : IEquatable< WeaponType > { public readonly ushort Value; public WeaponType( ushort value ) => Value = value; - public static implicit operator WeaponType( ushort id ) => new( id ); + public static implicit operator WeaponType( ushort id ) + => new( id ); public static explicit operator ushort( WeaponType id ) => id.Value; @@ -26,4 +27,4 @@ namespace Penumbra.GameData.Structs public override int GetHashCode() => Value.GetHashCode(); } -} +} \ No newline at end of file diff --git a/Penumbra.PlayerWatch/PlayerWatcher.cs b/Penumbra.PlayerWatch/PlayerWatcher.cs index e9644dd3..7f1a1df3 100644 --- a/Penumbra.PlayerWatch/PlayerWatcher.cs +++ b/Penumbra.PlayerWatch/PlayerWatcher.cs @@ -5,7 +5,7 @@ using Penumbra.GameData.Structs; namespace Penumbra.PlayerWatch { - public class PlayerWatcher : IDisposable, IPlayerWatcher + public class PlayerWatcher : IPlayerWatcher { public int Version { get; } = 1; diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index ef00d18f..3affe8a8 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -1,27 +1,23 @@ using System; -using System.Linq; using Dalamud.Game.ClientState.Actors.Types; -using ImGuiNET; namespace Penumbra.Api { public class PenumbraApi : IDisposable, IPenumbraApi { public int ApiVersion { get; } = 1; - private bool _initialized = false; private readonly Plugin _plugin; + public bool Valid { get; private set; } = false; public PenumbraApi( Plugin penumbra ) { - _plugin = penumbra; - //_plugin.SettingsInterface.ChangedItemClicked += TriggerChangedItemClicked; - _initialized = true; + _plugin = penumbra; + Valid = true; } public void Dispose() { - //_plugin.SettingsInterface.ChangedItemClicked -= TriggerChangedItemClicked; - _initialized = false; + Valid = false; } public event ChangedItemClick? ChangedItemClicked; @@ -39,7 +35,7 @@ namespace Penumbra.Api private void CheckInitialized() { - if( !_initialized ) + if( !Valid ) { throw new Exception( "PluginShare is not initialized." ); } @@ -65,8 +61,5 @@ namespace Penumbra.Api _plugin.ActorRefresher.RedrawAll( setting ); } - - public bool Valid - => _initialized; } } \ No newline at end of file diff --git a/Penumbra/Importer/TexToolsMeta.cs b/Penumbra/Importer/TexToolsMeta.cs index 9182e150..5917daba 100644 --- a/Penumbra/Importer/TexToolsMeta.cs +++ b/Penumbra/Importer/TexToolsMeta.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text.RegularExpressions; using Dalamud.Plugin; using Lumina.Data.Files; -using Penumbra.GameData; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Penumbra.GameData.Util; @@ -113,14 +112,14 @@ namespace Penumbra.Importer { case ObjectType.Equipment: case ObjectType.Accessory: - if( GameData.Enums.Names.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) ) + if( Names.SuffixToEquipSlot.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpSlot ) ) { EquipSlot = tmpSlot; } break; case ObjectType.Character: - if( GameData.Enums.Names.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) ) + if( Names.SuffixToCustomizationType.TryGetValue( match.Groups[ "Slot" ].Value, out var tmpCustom ) ) { CustomizationType = tmpCustom; } @@ -130,7 +129,7 @@ namespace Penumbra.Importer } if( match.Groups[ "SecondaryType" ].Success - && GameData.Enums.Names.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) ) + && Names.StringToBodySlot.TryGetValue( match.Groups[ "SecondaryType" ].Value, out SecondaryType ) ) { SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value ); } diff --git a/Penumbra/Interop/ActorRefresher.cs b/Penumbra/Interop/ActorRefresher.cs index 6d1454c0..c56780da 100644 --- a/Penumbra/Interop/ActorRefresher.cs +++ b/Penumbra/Interop/ActorRefresher.cs @@ -32,8 +32,8 @@ namespace Penumbra.Interop private const int NpcActorId = -536870912; public const int GPosePlayerActorIdx = 201; - private readonly DalamudPluginInterface _pi; - private readonly ModManager _mods; + private readonly DalamudPluginInterface _pi; + private readonly ModManager _mods; private readonly Queue< (int actorId, string name, RedrawType s) > _actorIds = new(); private int _currentFrame = 0; @@ -41,7 +41,7 @@ namespace Penumbra.Interop private int _currentActorId = -1; private string? _currentActorName = null; private LoadingFlags _currentActorStartState = 0; - private RedrawType _currentActorRedrawType = RedrawType.Unload; + private RedrawType _currentActorRedrawType = RedrawType.Unload; public static IntPtr RenderPtr( Actor actor ) => actor.Address + RenderModeOffset; @@ -153,11 +153,11 @@ namespace Penumbra.Interop { if( _actorIds.Count > 0 ) { - var (id, name, s) = _actorIds.Dequeue(); - _currentActorName = name; - _currentActorId = id; + var (id, name, s) = _actorIds.Dequeue(); + _currentActorName = name; + _currentActorId = id; _currentActorRedrawType = s; - var (actor, idx) = FindCurrentActor(); + var (actor, _) = FindCurrentActor(); if( actor == null ) { return; @@ -232,7 +232,7 @@ namespace Penumbra.Interop private void RevertSettings() { - var (actor, idx) = FindCurrentActor(); + var (actor, _) = FindCurrentActor(); if( actor != null ) { if( !StillLoading( RenderPtr( actor ) ) ) diff --git a/Penumbra/Meta/MetaCollection.cs b/Penumbra/Meta/MetaCollection.cs index a6648869..b8e42f7f 100644 --- a/Penumbra/Meta/MetaCollection.cs +++ b/Penumbra/Meta/MetaCollection.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Net; using Dalamud.Plugin; using Newtonsoft.Json; using Penumbra.Importer; diff --git a/Penumbra/Meta/MetaManager.cs b/Penumbra/Meta/MetaManager.cs index d439c1c7..1ca8fa39 100644 --- a/Penumbra/Meta/MetaManager.cs +++ b/Penumbra/Meta/MetaManager.cs @@ -121,10 +121,10 @@ namespace Penumbra.Meta public MetaManager( string name, Dictionary< GamePath, FileInfo > resolvedFiles, DirectoryInfo modDir ) { - _resolvedFiles = resolvedFiles; - _default = Service< MetaDefaults >.Get(); + _resolvedFiles = resolvedFiles; + _default = Service< MetaDefaults >.Get(); _resourceManagement = Service< GameResourceManagement >.Get(); - _dir = new DirectoryInfo( Path.Combine( modDir.FullName, TmpDirectory, name.ReplaceBadXivSymbols() ) ); + _dir = new DirectoryInfo( Path.Combine( modDir.FullName, TmpDirectory, name.ReplaceBadXivSymbols() ) ); ClearDirectory(); } diff --git a/Penumbra/Mod/ModCache.cs b/Penumbra/Mod/ModCache.cs index 501da640..accb1272 100644 --- a/Penumbra/Mod/ModCache.cs +++ b/Penumbra/Mod/ModCache.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using Penumbra.GameData.Util; using Penumbra.Meta; -using Penumbra.Util; namespace Penumbra.Mod { diff --git a/Penumbra/Mod/ModData.cs b/Penumbra/Mod/ModData.cs index d359f412..b9087872 100644 --- a/Penumbra/Mod/ModData.cs +++ b/Penumbra/Mod/ModData.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Dalamud.Plugin; -using Penumbra.GameData; using Penumbra.Util; namespace Penumbra.Mod diff --git a/Penumbra/Mod/ModMeta.cs b/Penumbra/Mod/ModMeta.cs index 302fbfc3..a9c674e3 100644 --- a/Penumbra/Mod/ModMeta.cs +++ b/Penumbra/Mod/ModMeta.cs @@ -6,7 +6,6 @@ using Dalamud.Plugin; using Newtonsoft.Json; using Penumbra.GameData.Util; using Penumbra.Structs; -using Penumbra.Util; namespace Penumbra.Mod { diff --git a/Penumbra/Mods/ModCollectionCache.cs b/Penumbra/Mods/ModCollectionCache.cs index 0ac716dc..95254a46 100644 --- a/Penumbra/Mods/ModCollectionCache.cs +++ b/Penumbra/Mods/ModCollectionCache.cs @@ -5,7 +5,6 @@ using System.Linq; using Penumbra.GameData.Util; using Penumbra.Meta; using Penumbra.Mod; -using Penumbra.Util; namespace Penumbra.Mods { diff --git a/Penumbra/Mods/ModManager.cs b/Penumbra/Mods/ModManager.cs index 8f47cdbb..f2ac48d8 100644 --- a/Penumbra/Mods/ModManager.cs +++ b/Penumbra/Mods/ModManager.cs @@ -6,7 +6,6 @@ using Dalamud.Plugin; using Penumbra.GameData.Util; using Penumbra.Meta; using Penumbra.Mod; -using Penumbra.Util; namespace Penumbra.Mods { diff --git a/Penumbra/UI/MenuTabs/TabCollections.cs b/Penumbra/UI/MenuTabs/TabCollections.cs index 947ab657..6e880260 100644 --- a/Penumbra/UI/MenuTabs/TabCollections.cs +++ b/Penumbra/UI/MenuTabs/TabCollections.cs @@ -30,7 +30,7 @@ namespace Penumbra.UI { _collections = _manager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray(); _collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0'; - _collectionNamesWithNone = "None\0" + _collectionNames; + _collectionNamesWithNone = "None\0" + _collectionNames; UpdateIndices(); } @@ -213,7 +213,8 @@ namespace Penumbra.UI if( ImGui.IsItemHovered() ) { - ImGui.SetTooltip( "A character collection will be used whenever you manually redraw a character with the Name you have set up.\n" + ImGui.SetTooltip( + "A character collection will be used whenever you manually redraw a character with the Name you have set up.\n" + "If you enable automatic character redraws in the Settings tab, penumbra will try to use Character collections for corresponding characters automatically.\n" ); } diff --git a/Penumbra/UI/MenuTabs/TabDebug.cs b/Penumbra/UI/MenuTabs/TabDebug.cs index 761f80f6..a5af5eaf 100644 --- a/Penumbra/UI/MenuTabs/TabDebug.cs +++ b/Penumbra/UI/MenuTabs/TabDebug.cs @@ -8,7 +8,6 @@ using System.Runtime.InteropServices; using Dalamud.Game.ClientState.Actors.Types; using ImGuiNET; using Penumbra.Api; -using Penumbra.GameData; using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Penumbra.GameData.Util; diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs index 99eaf40e..800a7ef9 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs @@ -1,9 +1,7 @@ -using System.Collections.Generic; using System.IO; using System.Linq; using Dalamud.Interface; using ImGuiNET; -using Lumina.Excel.GeneratedSheets; using Penumbra.Api; using Penumbra.GameData.Util; using Penumbra.Meta; diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsManipulations.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsManipulations.cs index 05dc4a5e..5026cc1e 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsManipulations.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsManipulations.cs @@ -31,91 +31,8 @@ namespace Penumbra.UI private int _newManipBodySlot = 0; private ushort _newManipVariant = 0; - private static readonly (string, EqpEntry)[] EqpAttributesBody = - { - ( "Enabled", EqpEntry.BodyEnabled ), - ( "Hide Waist", EqpEntry.BodyHideWaist ), - ( "Hide Small Gloves", EqpEntry.BodyHideGlovesS ), - ( "Hide Medium Gloves", EqpEntry.BodyHideGlovesM ), - ( "Hide Large Gloves", EqpEntry.BodyHideGlovesL ), - ( "Hide Gorget", EqpEntry.BodyHideGorget ), - ( "Show Legs", EqpEntry.BodyShowLeg ), - ( "Show Hands", EqpEntry.BodyShowHand ), - ( "Show Head", EqpEntry.BodyShowHead ), - ( "Show Necklace", EqpEntry.BodyShowNecklace ), - ( "Show Bracelet", EqpEntry.BodyShowBracelet ), - ( "Show Tail", EqpEntry.BodyShowTail ), - ( "Unknown 2", EqpEntry._2 ), - ( "Unknown 4", EqpEntry._4 ), - ( "Unknown 14", EqpEntry._14 ), - ( "Unknown 15", EqpEntry._15 ), - }; - private static readonly (string, EqpEntry)[] EqpAttributesLegs = - { - ( "Enabled", EqpEntry.LegsEnabled ), - ( "Hide Kneepads", EqpEntry.LegsHideKneePads ), - ( "Hide Small Boots", EqpEntry.LegsHideBootsS ), - ( "Hide Medium Boots", EqpEntry.LegsHideBootsM ), - ( "Hide Show Foot", EqpEntry.LegsShowFoot ), - ( "Hide Show Tail", EqpEntry.LegsShowTail ), - ( "Unknown 20", EqpEntry._20 ), - ( "Unknown 23", EqpEntry._23 ), - }; - - private static readonly (string, EqpEntry)[] EqpAttributesHands = - { - ( "Enabled", EqpEntry.HandsEnabled ), - ( "Hide Elbow", EqpEntry.HandsHideElbow ), - ( "Hide Forearm", EqpEntry.HandsHideForearm ), - ( "Show Bracelet", EqpEntry.HandShowBracelet ), - ( "Show Left Ring", EqpEntry.HandShowRingL ), - ( "Show Right Ring", EqpEntry.HandShowRingR ), - ( "Unknown 27", EqpEntry._27 ), - ( "Unknown 31", EqpEntry._31 ), - }; - - private static readonly (string, EqpEntry)[] EqpAttributesFeet = - { - ( "Enabled", EqpEntry.FeetEnabled ), - ( "Hide Knees", EqpEntry.FeetHideKnee ), - ( "Hide Calfs", EqpEntry.FeetHideCalf ), - ( "Hide Ankles", EqpEntry.FeetHideAnkle ), - ( "Unknown 36", EqpEntry._36 ), - ( "Unknown 37", EqpEntry._37 ), - ( "Unknown 38", EqpEntry._38 ), - ( "Unknown 39", EqpEntry._39 ), - }; - - private static readonly (string, EqpEntry)[] EqpAttributesHead = - { - ( "Enabled", EqpEntry.HeadEnabled ), - ( "Hide Scalp", EqpEntry.HeadHideScalp ), - ( "Hide Hair", EqpEntry.HeadHideHair ), - ( "Show Hair Override", EqpEntry.HeadShowHairOverride ), - ( "Hide Neck", EqpEntry.HeadHideNeck ), - ( "Show Necklace", EqpEntry.HeadShowNecklace ), - ( "Show Earrings", EqpEntry.HeadShowEarrings ), - ( "Show Earrings (Human)", EqpEntry.HeadShowEarringsHuman ), - ( "Show Earrings (Au Ra)", EqpEntry.HeadShowEarringsAura ), - ( "Show Ears (Human)", EqpEntry.HeadShowEarHuman ), - ( "Show Ears (Miqo'te)", EqpEntry.HeadShowEarMiqote ), - ( "Show Ears (Au Ra)", EqpEntry.HeadShowEarAuRa ), - ( "Show Ears (Viera)", EqpEntry.HeadShowEarViera ), - ( "Show on Hrothgar", EqpEntry.HeadShowHrothgarHat ), - ( "Show on Viera", EqpEntry.HeadShowVieraHat ), - ( "Unknown 46", EqpEntry._46 ), - ( "Unknown 54", EqpEntry._54 ), - ( "Unknown 55", EqpEntry._55 ), - ( "Unknown 58", EqpEntry._58 ), - ( "Unknown 59", EqpEntry._59 ), - ( "Unknown 60", EqpEntry._60 ), - ( "Unknown 61", EqpEntry._61 ), - ( "Unknown 62", EqpEntry._62 ), - ( "Unknown 63", EqpEntry._63 ), - }; - - private static readonly (string, EquipSlot)[] EqpEquipSlots = new[] + private static readonly (string, EquipSlot)[] EqpEquipSlots = { ( "Head", EquipSlot.Head ), ( "Body", EquipSlot.Body ), @@ -124,7 +41,7 @@ namespace Penumbra.UI ( "Feet", EquipSlot.Feet ), }; - private static readonly (string, EquipSlot)[] EqdpEquipSlots = new[] + private static readonly (string, EquipSlot)[] EqdpEquipSlots = { EqpEquipSlots[ 0 ], EqpEquipSlots[ 1 ], @@ -138,7 +55,7 @@ namespace Penumbra.UI ( "Right Finger", EquipSlot.RingR ), }; - private static readonly (string, Race)[] Races = new[] + private static readonly (string, Race)[] Races = { ( Race.Midlander.ToName(), Race.Midlander ), ( Race.Highlander.ToName(), Race.Highlander ), @@ -151,7 +68,7 @@ namespace Penumbra.UI ( Race.Hrothgar.ToName(), Race.Hrothgar ), }; - private static readonly (string, Gender)[] Genders = new[] + private static readonly (string, Gender)[] Genders = { ( Gender.Male.ToName(), Gender.Male ), ( Gender.Female.ToName(), Gender.Female ), @@ -159,25 +76,25 @@ namespace Penumbra.UI ( Gender.FemaleNpc.ToName(), Gender.FemaleNpc ), }; - private static readonly (string, ObjectType)[] ObjectTypes = new[] + private static readonly (string, ObjectType)[] ObjectTypes = { ( "Equipment", ObjectType.Equipment ), ( "Customization", ObjectType.Character ), }; - private static readonly (string, EquipSlot)[] EstEquipSlots = new[] + private static readonly (string, EquipSlot)[] EstEquipSlots = { EqpEquipSlots[ 0 ], EqpEquipSlots[ 1 ], }; - private static readonly (string, BodySlot)[] EstBodySlots = new[] + private static readonly (string, BodySlot)[] EstBodySlots = { ( "Hair", BodySlot.Hair ), ( "Face", BodySlot.Face ), }; - private static readonly (string, SubRace)[] Subraces = new[] + private static readonly (string, SubRace)[] Subraces = { ( SubRace.Midlander.ToName(), SubRace.Midlander ), ( SubRace.Highlander.ToName(), SubRace.Highlander ), @@ -197,25 +114,25 @@ namespace Penumbra.UI ( SubRace.Lost.ToName(), SubRace.Lost ), }; - private static readonly (string, RspAttribute)[] RspAttributes = new[] + private static readonly (string, RspAttribute)[] RspAttributes = { - ( "Male Minimum Size", RspAttribute.MaleMinSize ), - ( "Male Maximum Size", RspAttribute.MaleMaxSize ), - ( "Female Minimum Size", RspAttribute.FemaleMinSize ), - ( "Female Maximum Size", RspAttribute.FemaleMaxSize ), - ( "Bust Minimum X-Axis", RspAttribute.BustMinX ), - ( "Bust Maximum X-Axis", RspAttribute.BustMaxX ), - ( "Bust Minimum Y-Axis", RspAttribute.BustMinY ), - ( "Bust Maximum Y-Axis", RspAttribute.BustMaxY ), - ( "Bust Minimum Z-Axis", RspAttribute.BustMinZ ), - ( "Bust Maximum Z-Axis", RspAttribute.BustMaxZ ), - ( "Male Minimum Tail Length", RspAttribute.MaleMinTail ), - ( "Male Maximum Tail Length", RspAttribute.MaleMaxTail ), - ( "Female Minimum Tail Length", RspAttribute.FemaleMinTail ), - ( "Female Maximum Tail Length", RspAttribute.FemaleMaxTail ), + ( RspAttribute.MaleMinSize.ToFullString(), RspAttribute.MaleMinSize ), + ( RspAttribute.MaleMaxSize.ToFullString(), RspAttribute.MaleMaxSize ), + ( RspAttribute.FemaleMinSize.ToFullString(), RspAttribute.FemaleMinSize ), + ( RspAttribute.FemaleMaxSize.ToFullString(), RspAttribute.FemaleMaxSize ), + ( RspAttribute.BustMinX.ToFullString(), RspAttribute.BustMinX ), + ( RspAttribute.BustMaxX.ToFullString(), RspAttribute.BustMaxX ), + ( RspAttribute.BustMinY.ToFullString(), RspAttribute.BustMinY ), + ( RspAttribute.BustMaxY.ToFullString(), RspAttribute.BustMaxY ), + ( RspAttribute.BustMinZ.ToFullString(), RspAttribute.BustMinZ ), + ( RspAttribute.BustMaxZ.ToFullString(), RspAttribute.BustMaxZ ), + ( RspAttribute.MaleMinTail.ToFullString(), RspAttribute.MaleMinTail ), + ( RspAttribute.MaleMaxTail.ToFullString(), RspAttribute.MaleMaxTail ), + ( RspAttribute.FemaleMinTail.ToFullString(), RspAttribute.FemaleMinTail ), + ( RspAttribute.FemaleMaxTail.ToFullString(), RspAttribute.FemaleMaxTail ), }; - private static readonly (string, ObjectType)[] ImcObjectType = new[] + private static readonly (string, ObjectType)[] ImcObjectType = { ObjectTypes[ 0 ], ( "Weapon", ObjectType.Weapon ), @@ -223,7 +140,7 @@ namespace Penumbra.UI ( "Monster", ObjectType.Monster ), }; - private static readonly (string, BodySlot)[] ImcBodySlots = new[] + private static readonly (string, BodySlot)[] ImcBodySlots = { EstBodySlots[ 0 ], EstBodySlots[ 1 ], @@ -310,20 +227,13 @@ namespace Penumbra.UI if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) ) { - var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!; - var attributes = id.Slot switch - { - EquipSlot.Head => EqpAttributesHead, - EquipSlot.Body => EqpAttributesBody, - EquipSlot.Hands => EqpAttributesHands, - EquipSlot.Legs => EqpAttributesLegs, - EquipSlot.Feet => EqpAttributesFeet, - _ => Array.Empty< (string, EqpEntry) >(), - }; + var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!; + var attributes = Eqp.EqpAttributes[ id.Slot ]; - foreach( var (name, flag) in attributes ) + foreach( var flag in attributes ) { - var tmp = val.HasFlag( flag ); + var name = flag.ToLocalName(); + var tmp = val.HasFlag( flag ); if( PrintCheckBox( $"{name}##manip", ref tmp, defaults.HasFlag( flag ) ) && _editMode && tmp != val.HasFlag( flag ) ) { list[ manipIdx ] = MetaManipulation.Eqp( id.Slot, id.SetId, tmp ? val | flag : val & ~flag ); @@ -593,9 +503,6 @@ namespace Penumbra.UI if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) ) { - var color = defaults < val ? ColorDarkGreen : - defaults > val ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] ); - if( DefaultButton( $"{( _editMode ? "Set to " : "" )}Default: {defaults:F3}##scaleManip", ref val, defaults ) && _editMode ) @@ -742,7 +649,7 @@ namespace Penumbra.UI CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot ); CustomCombo( "Race", Races, out var race, ref _newManipRace ); CustomCombo( "Gender", Genders, out var gender, ref _newManipGender ); - newManip = MetaManipulation.Eqdp( equipSlot, GameData.Enums.Names.CombinedRace( gender, race ), ( ushort )_newManipSetId, + newManip = MetaManipulation.Eqdp( equipSlot, Names.CombinedRace( gender, race ), ( ushort )_newManipSetId, new EqdpEntry() ); break; } @@ -771,7 +678,7 @@ namespace Penumbra.UI CustomCombo( "Race", Races, out var race, ref _newManipRace ); CustomCombo( "Gender", Genders, out var gender, ref _newManipGender ); - newManip = MetaManipulation.Est( objectType, equipSlot, GameData.Enums.Names.CombinedRace( gender, race ), bodySlot, + newManip = MetaManipulation.Est( objectType, equipSlot, Names.CombinedRace( gender, race ), bodySlot, ( ushort )_newManipSetId, 0 ); break; } diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledModPanel.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledModPanel.cs index 8b3a3ad3..edec8a0e 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledModPanel.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledModPanel.cs @@ -2,7 +2,6 @@ using System; using System.Diagnostics; using System.IO; using System.Numerics; -using System.Windows.Forms; using Dalamud.Plugin; using ImGuiNET; using Penumbra.Mod; @@ -233,7 +232,7 @@ namespace Penumbra.UI } } - public static bool DrawSortOrder(ModData mod, ModManager manager, Selector selector) + public static bool DrawSortOrder( ModData mod, ModManager manager, Selector selector ) { var currentSortOrder = mod.SortOrder; ImGui.SetNextItemWidth( 300 ); @@ -503,7 +502,7 @@ namespace Penumbra.UI ImGui.SameLine(); DrawNormalizeButton(); - DrawSortOrder(Mod!.Data, _modManager, _selector); + DrawSortOrder( Mod!.Data, _modManager, _selector ); } public void Draw() diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledSelector.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledSelector.cs index 1f8c1d4c..b107b10a 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledSelector.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledSelector.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing.Configuration; using System.IO; using System.Linq; using System.Numerics; @@ -157,7 +156,7 @@ namespace Penumbra.UI var modMeta = new ModMeta { Author = "Unknown", - Name = newName.Replace('/', '\\'), + Name = newName.Replace( '/', '\\' ), Description = string.Empty, }; @@ -336,7 +335,7 @@ namespace Penumbra.UI ImGui.SameLine(); DrawModHelpButton(); ImGui.SameLine(); - DrawModTrashButton(); + DrawModTrashButton(); ImGui.PopStyleVar( 3 ); @@ -371,7 +370,7 @@ namespace Penumbra.UI ImGui.Text( "Are you sure you want to delete the following mod:" ); // todo: why the fuck does this become null?????? ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() / 2 ) ); - ImGui.TextColored( new Vector4( 0.7f, 0.1f, 0.1f, 1 ), Mod.Data.Meta.Name ?? "Unknown" ); + ImGui.TextColored( new Vector4( 0.7f, 0.1f, 0.1f, 1 ), Mod.Data.Meta.Name ); ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() ) / 2 ); var buttonSize = new Vector2( 120, 0 ); @@ -421,7 +420,7 @@ namespace Penumbra.UI && !CheckFlags( mod.Data.Resources.MetaManipulations.Count, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations ) && !CheckFlags( mod.Data.Meta.HasGroupsWithConfig ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig ); - private void DrawModOrderPopup( string popupName, Mod.Mod mod, int modIndex, bool firstOpen ) + private void DrawModOrderPopup( string popupName, Mod.Mod mod, bool firstOpen ) { if( !ImGui.BeginPopup( popupName ) ) { @@ -505,7 +504,7 @@ namespace Penumbra.UI firstOpen = true; } - DrawModOrderPopup( popupName, mod, modIndex, firstOpen ); + DrawModOrderPopup( popupName, mod, firstOpen ); if( selected ) { diff --git a/Penumbra/UI/SettingsInterface.cs b/Penumbra/UI/SettingsInterface.cs index a82726af..09ef89f8 100644 --- a/Penumbra/UI/SettingsInterface.cs +++ b/Penumbra/UI/SettingsInterface.cs @@ -1,4 +1,3 @@ -using System.IO; using System.Numerics; using Penumbra.Mods; using Penumbra.Util; diff --git a/Penumbra/Util/RelPath.cs b/Penumbra/Util/RelPath.cs index 6eaf8023..48c6b059 100644 --- a/Penumbra/Util/RelPath.cs +++ b/Penumbra/Util/RelPath.cs @@ -1,8 +1,6 @@ using System; using System.IO; using System.Linq; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Penumbra.GameData.Util; namespace Penumbra.Util diff --git a/Penumbra/Util/TempFile.cs b/Penumbra/Util/TempFile.cs index 5a819d25..60a25b49 100644 --- a/Penumbra/Util/TempFile.cs +++ b/Penumbra/Util/TempFile.cs @@ -5,13 +5,14 @@ namespace Penumbra.Util { public static class TempFile { - public static FileInfo TempFileName( DirectoryInfo baseDir, string suffix = "") + public static FileInfo TempFileName( DirectoryInfo baseDir, string suffix = "" ) { const uint maxTries = 15; for( var i = 0; i < maxTries; ++i ) { var name = Path.GetRandomFileName(); - var path = new FileInfo( Path.Combine( baseDir.FullName, suffix.Any() ? name.Substring( 0, name.LastIndexOf( '.' ) ) + suffix : name ) ); + var path = new FileInfo( Path.Combine( baseDir.FullName, + suffix.Any() ? name.Substring( 0, name.LastIndexOf( '.' ) ) + suffix : name ) ); if( !path.Exists ) { return path;