General formatting and cleanup.

This commit is contained in:
Ottermandias 2021-07-26 16:17:20 +02:00
parent 2b46397e8e
commit 12ee42df8e
29 changed files with 289 additions and 197 deletions

View file

@ -1,4 +1,3 @@
using System;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Actors.Types;
namespace Penumbra.Api namespace Penumbra.Api

View file

@ -1,3 +1,5 @@
using System.ComponentModel;
namespace Penumbra.GameData.Enums namespace Penumbra.GameData.Enums
{ {
public enum RspAttribute : byte 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(),
};
}
} }
} }

View file

@ -19,12 +19,13 @@ namespace Penumbra.GameData
return Identification; return Identification;
} }
public static IObjectIdentifier GetIdentifier( ) public static IObjectIdentifier GetIdentifier()
{ {
if( Identification == null ) if( Identification == null )
{ {
throw new Exception( "Object Identification was not initialized." ); throw new Exception( "Object Identification was not initialized." );
} }
return Identification; return Identification;
} }

View file

@ -122,7 +122,7 @@ namespace Penumbra.GameData
private (FileType, ObjectType, Match?) ParseGamePath( GamePath path ) 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; fileType = FileType.Unknown;
} }
@ -165,8 +165,8 @@ namespace Penumbra.GameData
return GameObjectInfo.Equipment( fileType, setId ); return GameObjectInfo.Equipment( fileType, setId );
} }
var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value ); var gr = Names.GenderRaceFromCode( groups[ "race" ].Value );
var slot = Enums.Names.SuffixToEquipSlot[ groups[ "slot" ].Value ]; var slot = Names.SuffixToEquipSlot[ groups[ "slot" ].Value ];
if( fileType == FileType.Model ) if( fileType == FileType.Model )
{ {
return GameObjectInfo.Equipment( fileType, setId, gr, slot ); return GameObjectInfo.Equipment( fileType, setId, gr, slot );
@ -211,7 +211,7 @@ namespace Penumbra.GameData
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId ); 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 ) if( fileType == FileType.Model )
{ {
return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot ); return GameObjectInfo.DemiHuman( fileType, demiHumanId, equipId, slot );
@ -236,10 +236,10 @@ namespace Penumbra.GameData
return GameObjectInfo.Customization( fileType, tmpType, id ); return GameObjectInfo.Customization( fileType, tmpType, id );
} }
var gr = Enums.Names.GenderRaceFromCode( groups[ "race" ].Value ); var gr = Names.GenderRaceFromCode( groups[ "race" ].Value );
var bodySlot = Enums.Names.StringToBodySlot[ groups[ "type" ].Value ]; var bodySlot = Names.StringToBodySlot[ groups[ "type" ].Value ];
var type = groups[ "slot" ].Success var type = groups[ "slot" ].Success
? Enums.Names.SuffixToCustomizationType[ groups[ "slot" ].Value ] ? Names.SuffixToCustomizationType[ groups[ "slot" ].Value ]
: CustomizationType.Skin; : CustomizationType.Skin;
if( fileType == FileType.Material ) if( fileType == FileType.Material )
{ {

View file

@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel; using System.ComponentModel;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
@ -126,5 +128,181 @@ namespace Penumbra.GameData.Structs
_ => 0, _ => 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,
};
} }
} }

View file

@ -2,14 +2,15 @@ using System;
namespace Penumbra.GameData.Structs namespace Penumbra.GameData.Structs
{ {
public readonly struct SetId : IComparable<SetId> public readonly struct SetId : IComparable< SetId >
{ {
public readonly ushort Value; public readonly ushort Value;
public SetId( ushort value ) public SetId( ushort value )
=> Value = 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 ) public static explicit operator ushort( SetId id )
=> id.Value; => id.Value;

View file

@ -2,14 +2,15 @@ using System;
namespace Penumbra.GameData.Structs namespace Penumbra.GameData.Structs
{ {
public readonly struct StainId : IEquatable<StainId> public readonly struct StainId : IEquatable< StainId >
{ {
public readonly byte Value; public readonly byte Value;
public StainId( byte value ) public StainId( byte value )
=> Value = 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 ) public static explicit operator byte( StainId id )
=> id.Value; => id.Value;

View file

@ -2,14 +2,15 @@ using System;
namespace Penumbra.GameData.Structs namespace Penumbra.GameData.Structs
{ {
public readonly struct WeaponType : IEquatable<WeaponType> public readonly struct WeaponType : IEquatable< WeaponType >
{ {
public readonly ushort Value; public readonly ushort Value;
public WeaponType( ushort value ) public WeaponType( ushort value )
=> Value = 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 ) public static explicit operator ushort( WeaponType id )
=> id.Value; => id.Value;

View file

@ -5,7 +5,7 @@ using Penumbra.GameData.Structs;
namespace Penumbra.PlayerWatch namespace Penumbra.PlayerWatch
{ {
public class PlayerWatcher : IDisposable, IPlayerWatcher public class PlayerWatcher : IPlayerWatcher
{ {
public int Version { get; } = 1; public int Version { get; } = 1;

View file

@ -1,27 +1,23 @@
using System; using System;
using System.Linq;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Actors.Types;
using ImGuiNET;
namespace Penumbra.Api namespace Penumbra.Api
{ {
public class PenumbraApi : IDisposable, IPenumbraApi public class PenumbraApi : IDisposable, IPenumbraApi
{ {
public int ApiVersion { get; } = 1; public int ApiVersion { get; } = 1;
private bool _initialized = false;
private readonly Plugin _plugin; private readonly Plugin _plugin;
public bool Valid { get; private set; } = false;
public PenumbraApi( Plugin penumbra ) public PenumbraApi( Plugin penumbra )
{ {
_plugin = penumbra; _plugin = penumbra;
//_plugin.SettingsInterface.ChangedItemClicked += TriggerChangedItemClicked; Valid = true;
_initialized = true;
} }
public void Dispose() public void Dispose()
{ {
//_plugin.SettingsInterface.ChangedItemClicked -= TriggerChangedItemClicked; Valid = false;
_initialized = false;
} }
public event ChangedItemClick? ChangedItemClicked; public event ChangedItemClick? ChangedItemClicked;
@ -39,7 +35,7 @@ namespace Penumbra.Api
private void CheckInitialized() private void CheckInitialized()
{ {
if( !_initialized ) if( !Valid )
{ {
throw new Exception( "PluginShare is not initialized." ); throw new Exception( "PluginShare is not initialized." );
} }
@ -65,8 +61,5 @@ namespace Penumbra.Api
_plugin.ActorRefresher.RedrawAll( setting ); _plugin.ActorRefresher.RedrawAll( setting );
} }
public bool Valid
=> _initialized;
} }
} }

View file

@ -4,7 +4,6 @@ using System.IO;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Dalamud.Plugin; using Dalamud.Plugin;
using Lumina.Data.Files; using Lumina.Data.Files;
using Penumbra.GameData;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
@ -113,14 +112,14 @@ namespace Penumbra.Importer
{ {
case ObjectType.Equipment: case ObjectType.Equipment:
case ObjectType.Accessory: 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; EquipSlot = tmpSlot;
} }
break; break;
case ObjectType.Character: 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; CustomizationType = tmpCustom;
} }
@ -130,7 +129,7 @@ namespace Penumbra.Importer
} }
if( match.Groups[ "SecondaryType" ].Success 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 ); SecondaryId = ushort.Parse( match.Groups[ "SecondaryId" ].Value );
} }

View file

@ -32,8 +32,8 @@ namespace Penumbra.Interop
private const int NpcActorId = -536870912; private const int NpcActorId = -536870912;
public const int GPosePlayerActorIdx = 201; public const int GPosePlayerActorIdx = 201;
private readonly DalamudPluginInterface _pi; private readonly DalamudPluginInterface _pi;
private readonly ModManager _mods; private readonly ModManager _mods;
private readonly Queue< (int actorId, string name, RedrawType s) > _actorIds = new(); private readonly Queue< (int actorId, string name, RedrawType s) > _actorIds = new();
private int _currentFrame = 0; private int _currentFrame = 0;
@ -41,7 +41,7 @@ namespace Penumbra.Interop
private int _currentActorId = -1; private int _currentActorId = -1;
private string? _currentActorName = null; private string? _currentActorName = null;
private LoadingFlags _currentActorStartState = 0; private LoadingFlags _currentActorStartState = 0;
private RedrawType _currentActorRedrawType = RedrawType.Unload; private RedrawType _currentActorRedrawType = RedrawType.Unload;
public static IntPtr RenderPtr( Actor actor ) public static IntPtr RenderPtr( Actor actor )
=> actor.Address + RenderModeOffset; => actor.Address + RenderModeOffset;
@ -153,11 +153,11 @@ namespace Penumbra.Interop
{ {
if( _actorIds.Count > 0 ) if( _actorIds.Count > 0 )
{ {
var (id, name, s) = _actorIds.Dequeue(); var (id, name, s) = _actorIds.Dequeue();
_currentActorName = name; _currentActorName = name;
_currentActorId = id; _currentActorId = id;
_currentActorRedrawType = s; _currentActorRedrawType = s;
var (actor, idx) = FindCurrentActor(); var (actor, _) = FindCurrentActor();
if( actor == null ) if( actor == null )
{ {
return; return;
@ -232,7 +232,7 @@ namespace Penumbra.Interop
private void RevertSettings() private void RevertSettings()
{ {
var (actor, idx) = FindCurrentActor(); var (actor, _) = FindCurrentActor();
if( actor != null ) if( actor != null )
{ {
if( !StillLoading( RenderPtr( actor ) ) ) if( !StillLoading( RenderPtr( actor ) ) )

View file

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net;
using Dalamud.Plugin; using Dalamud.Plugin;
using Newtonsoft.Json; using Newtonsoft.Json;
using Penumbra.Importer; using Penumbra.Importer;

View file

@ -121,10 +121,10 @@ namespace Penumbra.Meta
public MetaManager( string name, Dictionary< GamePath, FileInfo > resolvedFiles, DirectoryInfo modDir ) public MetaManager( string name, Dictionary< GamePath, FileInfo > resolvedFiles, DirectoryInfo modDir )
{ {
_resolvedFiles = resolvedFiles; _resolvedFiles = resolvedFiles;
_default = Service< MetaDefaults >.Get(); _default = Service< MetaDefaults >.Get();
_resourceManagement = Service< GameResourceManagement >.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(); ClearDirectory();
} }

View file

@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Util;
namespace Penumbra.Mod namespace Penumbra.Mod
{ {

View file

@ -2,7 +2,6 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Dalamud.Plugin; using Dalamud.Plugin;
using Penumbra.GameData;
using Penumbra.Util; using Penumbra.Util;
namespace Penumbra.Mod namespace Penumbra.Mod

View file

@ -6,7 +6,6 @@ using Dalamud.Plugin;
using Newtonsoft.Json; using Newtonsoft.Json;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
using Penumbra.Structs; using Penumbra.Structs;
using Penumbra.Util;
namespace Penumbra.Mod namespace Penumbra.Mod
{ {

View file

@ -5,7 +5,6 @@ using System.Linq;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Mod; using Penumbra.Mod;
using Penumbra.Util;
namespace Penumbra.Mods namespace Penumbra.Mods
{ {

View file

@ -6,7 +6,6 @@ using Dalamud.Plugin;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Mod; using Penumbra.Mod;
using Penumbra.Util;
namespace Penumbra.Mods namespace Penumbra.Mods
{ {

View file

@ -30,7 +30,7 @@ namespace Penumbra.UI
{ {
_collections = _manager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray(); _collections = _manager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray();
_collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0'; _collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0';
_collectionNamesWithNone = "None\0" + _collectionNames; _collectionNamesWithNone = "None\0" + _collectionNames;
UpdateIndices(); UpdateIndices();
} }
@ -213,7 +213,8 @@ namespace Penumbra.UI
if( ImGui.IsItemHovered() ) 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" ); + "If you enable automatic character redraws in the Settings tab, penumbra will try to use Character collections for corresponding characters automatically.\n" );
} }

View file

@ -8,7 +8,6 @@ using System.Runtime.InteropServices;
using Dalamud.Game.ClientState.Actors.Types; using Dalamud.Game.ClientState.Actors.Types;
using ImGuiNET; using ImGuiNET;
using Penumbra.Api; using Penumbra.Api;
using Penumbra.GameData;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;

View file

@ -1,9 +1,7 @@
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Dalamud.Interface; using Dalamud.Interface;
using ImGuiNET; using ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Penumbra.Api; using Penumbra.Api;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
using Penumbra.Meta; using Penumbra.Meta;

View file

@ -31,91 +31,8 @@ namespace Penumbra.UI
private int _newManipBodySlot = 0; private int _newManipBodySlot = 0;
private ushort _newManipVariant = 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 = private static readonly (string, EquipSlot)[] EqpEquipSlots =
{
( "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[]
{ {
( "Head", EquipSlot.Head ), ( "Head", EquipSlot.Head ),
( "Body", EquipSlot.Body ), ( "Body", EquipSlot.Body ),
@ -124,7 +41,7 @@ namespace Penumbra.UI
( "Feet", EquipSlot.Feet ), ( "Feet", EquipSlot.Feet ),
}; };
private static readonly (string, EquipSlot)[] EqdpEquipSlots = new[] private static readonly (string, EquipSlot)[] EqdpEquipSlots =
{ {
EqpEquipSlots[ 0 ], EqpEquipSlots[ 0 ],
EqpEquipSlots[ 1 ], EqpEquipSlots[ 1 ],
@ -138,7 +55,7 @@ namespace Penumbra.UI
( "Right Finger", EquipSlot.RingR ), ( "Right Finger", EquipSlot.RingR ),
}; };
private static readonly (string, Race)[] Races = new[] private static readonly (string, Race)[] Races =
{ {
( Race.Midlander.ToName(), Race.Midlander ), ( Race.Midlander.ToName(), Race.Midlander ),
( Race.Highlander.ToName(), Race.Highlander ), ( Race.Highlander.ToName(), Race.Highlander ),
@ -151,7 +68,7 @@ namespace Penumbra.UI
( Race.Hrothgar.ToName(), Race.Hrothgar ), ( Race.Hrothgar.ToName(), Race.Hrothgar ),
}; };
private static readonly (string, Gender)[] Genders = new[] private static readonly (string, Gender)[] Genders =
{ {
( Gender.Male.ToName(), Gender.Male ), ( Gender.Male.ToName(), Gender.Male ),
( Gender.Female.ToName(), Gender.Female ), ( Gender.Female.ToName(), Gender.Female ),
@ -159,25 +76,25 @@ namespace Penumbra.UI
( Gender.FemaleNpc.ToName(), Gender.FemaleNpc ), ( Gender.FemaleNpc.ToName(), Gender.FemaleNpc ),
}; };
private static readonly (string, ObjectType)[] ObjectTypes = new[] private static readonly (string, ObjectType)[] ObjectTypes =
{ {
( "Equipment", ObjectType.Equipment ), ( "Equipment", ObjectType.Equipment ),
( "Customization", ObjectType.Character ), ( "Customization", ObjectType.Character ),
}; };
private static readonly (string, EquipSlot)[] EstEquipSlots = new[] private static readonly (string, EquipSlot)[] EstEquipSlots =
{ {
EqpEquipSlots[ 0 ], EqpEquipSlots[ 0 ],
EqpEquipSlots[ 1 ], EqpEquipSlots[ 1 ],
}; };
private static readonly (string, BodySlot)[] EstBodySlots = new[] private static readonly (string, BodySlot)[] EstBodySlots =
{ {
( "Hair", BodySlot.Hair ), ( "Hair", BodySlot.Hair ),
( "Face", BodySlot.Face ), ( "Face", BodySlot.Face ),
}; };
private static readonly (string, SubRace)[] Subraces = new[] private static readonly (string, SubRace)[] Subraces =
{ {
( SubRace.Midlander.ToName(), SubRace.Midlander ), ( SubRace.Midlander.ToName(), SubRace.Midlander ),
( SubRace.Highlander.ToName(), SubRace.Highlander ), ( SubRace.Highlander.ToName(), SubRace.Highlander ),
@ -197,25 +114,25 @@ namespace Penumbra.UI
( SubRace.Lost.ToName(), SubRace.Lost ), ( SubRace.Lost.ToName(), SubRace.Lost ),
}; };
private static readonly (string, RspAttribute)[] RspAttributes = new[] private static readonly (string, RspAttribute)[] RspAttributes =
{ {
( "Male Minimum Size", RspAttribute.MaleMinSize ), ( RspAttribute.MaleMinSize.ToFullString(), RspAttribute.MaleMinSize ),
( "Male Maximum Size", RspAttribute.MaleMaxSize ), ( RspAttribute.MaleMaxSize.ToFullString(), RspAttribute.MaleMaxSize ),
( "Female Minimum Size", RspAttribute.FemaleMinSize ), ( RspAttribute.FemaleMinSize.ToFullString(), RspAttribute.FemaleMinSize ),
( "Female Maximum Size", RspAttribute.FemaleMaxSize ), ( RspAttribute.FemaleMaxSize.ToFullString(), RspAttribute.FemaleMaxSize ),
( "Bust Minimum X-Axis", RspAttribute.BustMinX ), ( RspAttribute.BustMinX.ToFullString(), RspAttribute.BustMinX ),
( "Bust Maximum X-Axis", RspAttribute.BustMaxX ), ( RspAttribute.BustMaxX.ToFullString(), RspAttribute.BustMaxX ),
( "Bust Minimum Y-Axis", RspAttribute.BustMinY ), ( RspAttribute.BustMinY.ToFullString(), RspAttribute.BustMinY ),
( "Bust Maximum Y-Axis", RspAttribute.BustMaxY ), ( RspAttribute.BustMaxY.ToFullString(), RspAttribute.BustMaxY ),
( "Bust Minimum Z-Axis", RspAttribute.BustMinZ ), ( RspAttribute.BustMinZ.ToFullString(), RspAttribute.BustMinZ ),
( "Bust Maximum Z-Axis", RspAttribute.BustMaxZ ), ( RspAttribute.BustMaxZ.ToFullString(), RspAttribute.BustMaxZ ),
( "Male Minimum Tail Length", RspAttribute.MaleMinTail ), ( RspAttribute.MaleMinTail.ToFullString(), RspAttribute.MaleMinTail ),
( "Male Maximum Tail Length", RspAttribute.MaleMaxTail ), ( RspAttribute.MaleMaxTail.ToFullString(), RspAttribute.MaleMaxTail ),
( "Female Minimum Tail Length", RspAttribute.FemaleMinTail ), ( RspAttribute.FemaleMinTail.ToFullString(), RspAttribute.FemaleMinTail ),
( "Female Maximum Tail Length", RspAttribute.FemaleMaxTail ), ( RspAttribute.FemaleMaxTail.ToFullString(), RspAttribute.FemaleMaxTail ),
}; };
private static readonly (string, ObjectType)[] ImcObjectType = new[] private static readonly (string, ObjectType)[] ImcObjectType =
{ {
ObjectTypes[ 0 ], ObjectTypes[ 0 ],
( "Weapon", ObjectType.Weapon ), ( "Weapon", ObjectType.Weapon ),
@ -223,7 +140,7 @@ namespace Penumbra.UI
( "Monster", ObjectType.Monster ), ( "Monster", ObjectType.Monster ),
}; };
private static readonly (string, BodySlot)[] ImcBodySlots = new[] private static readonly (string, BodySlot)[] ImcBodySlots =
{ {
EstBodySlots[ 0 ], EstBodySlots[ 0 ],
EstBodySlots[ 1 ], EstBodySlots[ 1 ],
@ -310,20 +227,13 @@ namespace Penumbra.UI
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) ) if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
{ {
var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!; var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
var attributes = id.Slot switch var attributes = Eqp.EqpAttributes[ id.Slot ];
{
EquipSlot.Head => EqpAttributesHead,
EquipSlot.Body => EqpAttributesBody,
EquipSlot.Hands => EqpAttributesHands,
EquipSlot.Legs => EqpAttributesLegs,
EquipSlot.Feet => EqpAttributesFeet,
_ => Array.Empty< (string, EqpEntry) >(),
};
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 ) ) 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 ); 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}" ) ) if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
{ {
var color = defaults < val ? ColorDarkGreen :
defaults > val ? ColorDarkRed : ImGui.ColorConvertFloat4ToU32( ImGui.GetStyle().Colors[ ( int )ImGuiCol.Button ] );
if( DefaultButton( if( DefaultButton(
$"{( _editMode ? "Set to " : "" )}Default: {defaults:F3}##scaleManip", ref val, defaults ) $"{( _editMode ? "Set to " : "" )}Default: {defaults:F3}##scaleManip", ref val, defaults )
&& _editMode ) && _editMode )
@ -742,7 +649,7 @@ namespace Penumbra.UI
CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot ); CustomCombo( "Equipment Slot", EqdpEquipSlots, out var equipSlot, ref _newManipEquipSlot );
CustomCombo( "Race", Races, out var race, ref _newManipRace ); CustomCombo( "Race", Races, out var race, ref _newManipRace );
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender ); 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() ); new EqdpEntry() );
break; break;
} }
@ -771,7 +678,7 @@ namespace Penumbra.UI
CustomCombo( "Race", Races, out var race, ref _newManipRace ); CustomCombo( "Race", Races, out var race, ref _newManipRace );
CustomCombo( "Gender", Genders, out var gender, ref _newManipGender ); 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 ); ( ushort )_newManipSetId, 0 );
break; break;
} }

View file

@ -2,7 +2,6 @@ using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Numerics; using System.Numerics;
using System.Windows.Forms;
using Dalamud.Plugin; using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
using Penumbra.Mod; 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; var currentSortOrder = mod.SortOrder;
ImGui.SetNextItemWidth( 300 ); ImGui.SetNextItemWidth( 300 );
@ -503,7 +502,7 @@ namespace Penumbra.UI
ImGui.SameLine(); ImGui.SameLine();
DrawNormalizeButton(); DrawNormalizeButton();
DrawSortOrder(Mod!.Data, _modManager, _selector); DrawSortOrder( Mod!.Data, _modManager, _selector );
} }
public void Draw() public void Draw()

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing.Configuration;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
@ -157,7 +156,7 @@ namespace Penumbra.UI
var modMeta = new ModMeta var modMeta = new ModMeta
{ {
Author = "Unknown", Author = "Unknown",
Name = newName.Replace('/', '\\'), Name = newName.Replace( '/', '\\' ),
Description = string.Empty, Description = string.Empty,
}; };
@ -371,7 +370,7 @@ namespace Penumbra.UI
ImGui.Text( "Are you sure you want to delete the following mod:" ); ImGui.Text( "Are you sure you want to delete the following mod:" );
// todo: why the fuck does this become null?????? // todo: why the fuck does this become null??????
ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() / 2 ) ); 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 ); ImGui.Dummy( new Vector2( ImGui.GetTextLineHeight() ) / 2 );
var buttonSize = new Vector2( 120, 0 ); 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.Resources.MetaManipulations.Count, ModFilter.HasNoMetaManipulations, ModFilter.HasMetaManipulations )
&& !CheckFlags( mod.Data.Meta.HasGroupsWithConfig ? 1 : 0, ModFilter.HasNoConfig, ModFilter.HasConfig ); && !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 ) ) if( !ImGui.BeginPopup( popupName ) )
{ {
@ -505,7 +504,7 @@ namespace Penumbra.UI
firstOpen = true; firstOpen = true;
} }
DrawModOrderPopup( popupName, mod, modIndex, firstOpen ); DrawModOrderPopup( popupName, mod, firstOpen );
if( selected ) if( selected )
{ {

View file

@ -1,4 +1,3 @@
using System.IO;
using System.Numerics; using System.Numerics;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Util; using Penumbra.Util;

View file

@ -1,8 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Penumbra.GameData.Util; using Penumbra.GameData.Util;
namespace Penumbra.Util namespace Penumbra.Util

View file

@ -5,13 +5,14 @@ namespace Penumbra.Util
{ {
public static class TempFile public static class TempFile
{ {
public static FileInfo TempFileName( DirectoryInfo baseDir, string suffix = "") public static FileInfo TempFileName( DirectoryInfo baseDir, string suffix = "" )
{ {
const uint maxTries = 15; const uint maxTries = 15;
for( var i = 0; i < maxTries; ++i ) for( var i = 0; i < maxTries; ++i )
{ {
var name = Path.GetRandomFileName(); 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 ) if( !path.Exists )
{ {
return path; return path;