mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Added a whole lot of rudimentary comments, also importing selects the last imported mod if possible.
This commit is contained in:
parent
a19ec226c5
commit
d29049ca21
24 changed files with 83 additions and 23 deletions
|
|
@ -27,6 +27,7 @@ namespace Penumbra.Game.Enums
|
||||||
Viera,
|
Viera,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The combined gender-race-npc numerical code as used by the game.
|
||||||
public enum GenderRace : ushort
|
public enum GenderRace : ushort
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ namespace Penumbra.Hooks
|
||||||
Marshal.GetDelegateForFunctionPointer< UnloadCharacterResourcePrototype >( unloadCharacterResourceAddress );
|
Marshal.GetDelegateForFunctionPointer< UnloadCharacterResourcePrototype >( unloadCharacterResourceAddress );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forces the reload of a specific set of 85 files, notably containing the eqp, eqdp, gmp and est tables, by filename.
|
||||||
public unsafe void ReloadPlayerResources()
|
public unsafe void ReloadPlayerResources()
|
||||||
{
|
{
|
||||||
ReloadCharacterResources();
|
ReloadCharacterResources();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ using Dalamud.Plugin;
|
||||||
|
|
||||||
namespace Penumbra.Hooks
|
namespace Penumbra.Hooks
|
||||||
{
|
{
|
||||||
|
// Use this to disable streaming of specific soundfiles,
|
||||||
|
// which will allow replacement of .scd files.
|
||||||
public unsafe class MusicManager
|
public unsafe class MusicManager
|
||||||
{
|
{
|
||||||
private readonly IntPtr _musicManager;
|
private readonly IntPtr _musicManager;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ namespace Penumbra.Importer
|
||||||
private const string TempFileName = "textools-import";
|
private const string TempFileName = "textools-import";
|
||||||
private readonly string _resolvedTempFilePath;
|
private readonly string _resolvedTempFilePath;
|
||||||
|
|
||||||
|
public DirectoryInfo? ExtractedDirectory { get; private set; }
|
||||||
|
|
||||||
public ImporterState State { get; private set; }
|
public ImporterState State { get; private set; }
|
||||||
|
|
||||||
public long TotalProgress { get; private set; }
|
public long TotalProgress { get; private set; }
|
||||||
|
|
@ -161,14 +163,14 @@ namespace Penumbra.Importer
|
||||||
// Open the mod data file from the modpack as a SqPackStream
|
// Open the mod data file from the modpack as a SqPackStream
|
||||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||||
|
|
||||||
var newModFolder = CreateModFolder( _outDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
ExtractedDirectory = CreateModFolder( _outDirectory, Path.GetFileNameWithoutExtension( modPackFile.Name ) );
|
||||||
|
|
||||||
File.WriteAllText(
|
File.WriteAllText(
|
||||||
Path.Combine( newModFolder.FullName, "meta.json" ),
|
Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||||
JsonConvert.SerializeObject( modMeta )
|
JsonConvert.SerializeObject( modMeta )
|
||||||
);
|
);
|
||||||
|
|
||||||
ExtractSimpleModList( newModFolder, modList, modData );
|
ExtractSimpleModList( ExtractedDirectory, modList, modData );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImportV2ModPack( FileInfo modPackFile, ZipFile extractedModPack, string modRaw )
|
private void ImportV2ModPack( FileInfo modPackFile, ZipFile extractedModPack, string modRaw )
|
||||||
|
|
@ -228,12 +230,12 @@ namespace Penumbra.Importer
|
||||||
// Open the mod data file from the modpack as a SqPackStream
|
// Open the mod data file from the modpack as a SqPackStream
|
||||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||||
|
|
||||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
ExtractedDirectory = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||||
|
|
||||||
File.WriteAllText( Path.Combine( newModFolder.FullName, "meta.json" ),
|
File.WriteAllText( Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||||
JsonConvert.SerializeObject( modMeta ) );
|
JsonConvert.SerializeObject( modMeta ) );
|
||||||
|
|
||||||
ExtractSimpleModList( newModFolder, modList.SimpleModsList ?? Enumerable.Empty< SimpleMod >(), modData );
|
ExtractSimpleModList( ExtractedDirectory, modList.SimpleModsList ?? Enumerable.Empty< SimpleMod >(), modData );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImportExtendedV2ModPack( ZipFile extractedModPack, string modRaw )
|
private void ImportExtendedV2ModPack( ZipFile extractedModPack, string modRaw )
|
||||||
|
|
@ -256,11 +258,11 @@ namespace Penumbra.Importer
|
||||||
// Open the mod data file from the modpack as a SqPackStream
|
// Open the mod data file from the modpack as a SqPackStream
|
||||||
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
using var modData = GetMagicSqPackDeleterStream( extractedModPack, "TTMPD.mpd" );
|
||||||
|
|
||||||
var newModFolder = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
ExtractedDirectory = CreateModFolder( _outDirectory, modList.Name ?? "New Mod" );
|
||||||
|
|
||||||
if( modList.SimpleModsList != null )
|
if( modList.SimpleModsList != null )
|
||||||
{
|
{
|
||||||
ExtractSimpleModList( newModFolder, modList.SimpleModsList, modData );
|
ExtractSimpleModList( ExtractedDirectory, modList.SimpleModsList, modData );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( modList.ModPackPages == null )
|
if( modList.ModPackPages == null )
|
||||||
|
|
@ -278,7 +280,7 @@ namespace Penumbra.Importer
|
||||||
|
|
||||||
foreach( var group in page.ModGroups.Where( group => group.GroupName != null && group.OptionList != null ) )
|
foreach( var group in page.ModGroups.Where( group => group.GroupName != null && group.OptionList != null ) )
|
||||||
{
|
{
|
||||||
var groupFolder = NewOptionDirectory( newModFolder, group.GroupName! );
|
var groupFolder = NewOptionDirectory( ExtractedDirectory, group.GroupName! );
|
||||||
if( groupFolder.Exists )
|
if( groupFolder.Exists )
|
||||||
{
|
{
|
||||||
groupFolder = new DirectoryInfo( groupFolder.FullName + $" ({page.PageIndex})" );
|
groupFolder = new DirectoryInfo( groupFolder.FullName + $" ({page.PageIndex})" );
|
||||||
|
|
@ -291,12 +293,12 @@ namespace Penumbra.Importer
|
||||||
ExtractSimpleModList( optionFolder, option.ModsJsons!, modData );
|
ExtractSimpleModList( optionFolder, option.ModsJsons!, modData );
|
||||||
}
|
}
|
||||||
|
|
||||||
AddMeta( newModFolder, groupFolder, group, modMeta );
|
AddMeta( ExtractedDirectory, groupFolder, group, modMeta );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File.WriteAllText(
|
File.WriteAllText(
|
||||||
Path.Combine( newModFolder.FullName, "meta.json" ),
|
Path.Combine( ExtractedDirectory.FullName, "meta.json" ),
|
||||||
JsonConvert.SerializeObject( modMeta, Formatting.Indented )
|
JsonConvert.SerializeObject( modMeta, Formatting.Indented )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,18 @@ using GameData = Penumbra.Game.Enums.GameData;
|
||||||
|
|
||||||
namespace Penumbra.Importer
|
namespace Penumbra.Importer
|
||||||
{
|
{
|
||||||
|
// TexTools provices custom generated *.meta files for its modpacks, that contain changes to
|
||||||
|
// - imc files
|
||||||
|
// - eqp files
|
||||||
|
// - gmp files
|
||||||
|
// - est files
|
||||||
|
// - eqdp files
|
||||||
|
// made by the mod. The filename determines to what the changes are applied, and the binary file itself contains changes.
|
||||||
|
// We parse every *.meta file in a mod and combine all actual changes that do not keep data on default values and that can be applied to the game in a .json.
|
||||||
|
// TexTools may also generate files that contain non-existing changes, e.g. *.imc files for weapon offhands, which will be ignored.
|
||||||
public class TexToolsMeta
|
public class TexToolsMeta
|
||||||
{
|
{
|
||||||
|
// The info class determines the files or table locations the changes need to apply to from the filename.
|
||||||
public class Info
|
public class Info
|
||||||
{
|
{
|
||||||
private const string Pt = @"(?'PrimaryType'[a-z]*)"; // language=regex
|
private const string Pt = @"(?'PrimaryType'[a-z]*)"; // language=regex
|
||||||
|
|
@ -28,6 +38,7 @@ namespace Penumbra.Importer
|
||||||
private const string Slot = @"(_(?'Slot'[a-z]{3}))?"; // language=regex
|
private const string Slot = @"(_(?'Slot'[a-z]{3}))?"; // language=regex
|
||||||
private const string Ext = @"\.meta";
|
private const string Ext = @"\.meta";
|
||||||
|
|
||||||
|
// These are the valid regexes for .meta files that we are able to support at the moment.
|
||||||
private static readonly Regex HousingMeta = new( $"bgcommon/hou/{Pt}/general/{Pi}/{Pir}{Ext}" );
|
private static readonly Regex HousingMeta = new( $"bgcommon/hou/{Pt}/general/{Pi}/{Pir}{Ext}" );
|
||||||
private static readonly Regex CharaMeta = new( $"chara/{Pt}/{Pp}{Pi}(/obj/{St}/{Sp}{Si})?/{File}{Slot}{Ext}" );
|
private static readonly Regex CharaMeta = new( $"chara/{Pt}/{Pp}{Pi}(/obj/{St}/{Sp}{Si})?/{File}{Slot}{Ext}" );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ namespace Penumbra.Meta.Files
|
||||||
{ }
|
{ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Imc files are already supported in Lumina, but changing the provided data is not supported.
|
||||||
|
// We use reflection and extension methods to support changing the data of a given Imc file.
|
||||||
public static class ImcExtensions
|
public static class ImcExtensions
|
||||||
{
|
{
|
||||||
public static ulong ToInteger( this ImcFile.ImageChangeData imc )
|
public static ulong ToInteger( this ImcFile.ImageChangeData imc )
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Meta.Files
|
namespace Penumbra.Meta.Files
|
||||||
{
|
{
|
||||||
|
// This class manages the default meta files obtained via lumina from the game files themselves.
|
||||||
|
// On first call, the default version of any supported file will be cached and can be returned without reparsing.
|
||||||
public class MetaDefaults
|
public class MetaDefaults
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly DalamudPluginInterface _pi;
|
||||||
|
|
@ -107,6 +109,7 @@ namespace Penumbra.Meta.Files
|
||||||
private FileResource FetchFile( string name )
|
private FileResource FetchFile( string name )
|
||||||
=> _pi.Data.GetFile( name );
|
=> _pi.Data.GetFile( name );
|
||||||
|
|
||||||
|
// Check that a given meta manipulation is an actual change to the default value. We don't need to keep changes to default.
|
||||||
public bool CheckAgainstDefault( MetaManipulation m )
|
public bool CheckAgainstDefault( MetaManipulation m )
|
||||||
{
|
{
|
||||||
return m.Type switch
|
return m.Type switch
|
||||||
|
|
@ -129,6 +132,7 @@ namespace Penumbra.Meta.Files
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a deep copy of a default file as a new file.
|
||||||
public object? CreateNewFile( MetaManipulation m )
|
public object? CreateNewFile( MetaManipulation m )
|
||||||
{
|
{
|
||||||
return m.Type switch
|
return m.Type switch
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Meta.Files
|
namespace Penumbra.Meta.Files
|
||||||
{
|
{
|
||||||
|
// Contains all filenames for meta changes depending on their parameters.
|
||||||
public static class MetaFileNames
|
public static class MetaFileNames
|
||||||
{
|
{
|
||||||
public static GamePath Eqp()
|
public static GamePath Eqp()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Penumbra.Game.Enums;
|
using Penumbra.Game.Enums;
|
||||||
|
|
||||||
|
|
||||||
|
// A struct for each type of meta change that contains all relevant information,
|
||||||
|
// to uniquely identify the corresponding file and location for the change.
|
||||||
|
// The first byte is guaranteed to be the MetaType enum for each case.
|
||||||
namespace Penumbra.Meta
|
namespace Penumbra.Meta
|
||||||
{
|
{
|
||||||
public enum MetaType : byte
|
public enum MetaType : byte
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ using ImcFile = Lumina.Data.Files.ImcFile;
|
||||||
|
|
||||||
namespace Penumbra.Meta
|
namespace Penumbra.Meta
|
||||||
{
|
{
|
||||||
|
// Write a single meta manipulation as a Base64string of the 16 bytes defining it.
|
||||||
public class MetaManipulationConverter : JsonConverter< MetaManipulation >
|
public class MetaManipulationConverter : JsonConverter< MetaManipulation >
|
||||||
{
|
{
|
||||||
public override void WriteJson( JsonWriter writer, MetaManipulation manip, JsonSerializer serializer )
|
public override void WriteJson( JsonWriter writer, MetaManipulation manip, JsonSerializer serializer )
|
||||||
|
|
@ -38,6 +39,10 @@ namespace Penumbra.Meta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A MetaManipulation is a union of a type of Identifier (first 8 bytes, cf. Identifier.cs)
|
||||||
|
// and the appropriate Value to change the meta entry to (the other 8 bytes).
|
||||||
|
// Its comparison for sorting and hashes depends only on the identifier.
|
||||||
|
// The first byte is guaranteed to be a MetaType enum value in any case, so Type can always be read.
|
||||||
[StructLayout( LayoutKind.Explicit )]
|
[StructLayout( LayoutKind.Explicit )]
|
||||||
[JsonConverter( typeof( MetaManipulationConverter ) )]
|
[JsonConverter( typeof( MetaManipulationConverter ) )]
|
||||||
public struct MetaManipulation : IComparable
|
public struct MetaManipulation : IComparable
|
||||||
|
|
@ -219,11 +224,11 @@ namespace Penumbra.Meta
|
||||||
{
|
{
|
||||||
return Type switch
|
return Type switch
|
||||||
{
|
{
|
||||||
MetaType.Eqp => $"EQP - {EqpIdentifier}",
|
MetaType.Eqp => EqpIdentifier.ToString(),
|
||||||
MetaType.Eqdp => $"EQDP - {EqdpIdentifier}",
|
MetaType.Eqdp => EqdpIdentifier.ToString(),
|
||||||
MetaType.Est => $"EST - {EstIdentifier}",
|
MetaType.Est => EstIdentifier.ToString(),
|
||||||
MetaType.Gmp => $"GMP - {GmpIdentifier}",
|
MetaType.Gmp => GmpIdentifier.ToString(),
|
||||||
MetaType.Imc => $"IMC - {ImcIdentifier}",
|
MetaType.Imc => ImcIdentifier.ToString(),
|
||||||
_ => throw new InvalidEnumArgumentException(),
|
_ => throw new InvalidEnumArgumentException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// A complete Mod containing settings (i.e. dependent on a collection)
|
||||||
|
// and the resulting cache.
|
||||||
public class Mod
|
public class Mod
|
||||||
{
|
{
|
||||||
public ModSettings Settings { get; }
|
public ModSettings Settings { get; }
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// The ModCache contains volatile information dependent on all current settings in a collection.
|
||||||
public class ModCache
|
public class ModCache
|
||||||
{
|
{
|
||||||
public Dictionary< Mod, (List< GamePath > Files, List< MetaManipulation > Manipulations) > Conflicts { get; private set; } = new();
|
public Dictionary< Mod, (List< GamePath > Files, List< MetaManipulation > Manipulations) > Conflicts { get; private set; } = new();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@ using Dalamud.Plugin;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// ModData contains all permanent information about a mod,
|
||||||
|
// and is independent of collections or settings.
|
||||||
|
// It only changes when the user actively changes the mod or their filesystem.
|
||||||
public class ModData
|
public class ModData
|
||||||
{
|
{
|
||||||
public DirectoryInfo BasePath;
|
public DirectoryInfo BasePath;
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// Functions that do not really depend on only one component of a mod.
|
||||||
public static class ModFunctions
|
public static class ModFunctions
|
||||||
{
|
{
|
||||||
public static bool CleanUpCollection( Dictionary< string, ModSettings > settings, IEnumerable< DirectoryInfo > modPaths )
|
public static bool CleanUpCollection( Dictionary< string, ModSettings > settings, IEnumerable< DirectoryInfo > modPaths )
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ namespace Penumbra.Mod
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static ModMeta? LoadFromFile( FileInfo filePath )
|
public static ModMeta? LoadFromFile( FileInfo filePath )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Penumbra.Structs;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// Contains the settings for a given mod.
|
||||||
public class ModSettings
|
public class ModSettings
|
||||||
{
|
{
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ using Penumbra.Structs;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
|
// Contains settings with the option selections stored by names instead of index.
|
||||||
|
// This is meant to make them possibly more portable when we support importing collections from other users.
|
||||||
|
// Enabled does not exist, because disabled mods would not be exported in this way.
|
||||||
public class NamedModSettings
|
public class NamedModSettings
|
||||||
{
|
{
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods
|
namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
|
// A ModCollection is a named set of ModSettings to all of the users' installed mods.
|
||||||
|
// It is meant to be local only, and thus should always contain settings for every mod, not just the enabled ones.
|
||||||
|
// Settings to mods that are not installed anymore are kept as long as no call to CleanUnavailableSettings is made.
|
||||||
|
// Active ModCollections build a cache of currently relevant data.
|
||||||
public class ModCollection
|
public class ModCollection
|
||||||
{
|
{
|
||||||
public const string DefaultCollection = "Default";
|
public const string DefaultCollection = "Default";
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods
|
namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
|
// The ModCollectionCache contains all required temporary data to use a collection.
|
||||||
|
// It will only be setup if a collection gets activated in any way.
|
||||||
public class ModCollectionCache
|
public class ModCollectionCache
|
||||||
{
|
{
|
||||||
public readonly List< Mod.Mod > AvailableMods = new();
|
public readonly List< Mod.Mod > AvailableMods = new();
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,11 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods
|
namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
|
// The ModManager handles the basic mods installed to the mod directory,
|
||||||
|
// as well as all saved collections.
|
||||||
|
// It also handles manual changes to mods that require changes in all collections,
|
||||||
|
// updating the state of a mod from the filesystem,
|
||||||
|
// and collection swapping.
|
||||||
public class ModManager
|
public class ModManager
|
||||||
{
|
{
|
||||||
private readonly Plugin _plugin;
|
private readonly Plugin _plugin;
|
||||||
|
|
@ -216,7 +221,6 @@ namespace Penumbra.Mods
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool UpdateMod( ModData mod, bool recomputeMeta = false )
|
public bool UpdateMod( ModData mod, bool recomputeMeta = false )
|
||||||
{
|
{
|
||||||
var oldName = mod.Meta.Name;
|
var oldName = mod.Meta.Name;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ using Penumbra.Structs;
|
||||||
|
|
||||||
namespace Penumbra.Mods
|
namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
|
// Extracted to keep the main file a bit more clean.
|
||||||
|
// Contains all change functions on a specific mod that also require corresponding changes to collections.
|
||||||
public static class ModManagerEditExtensions
|
public static class ModManagerEditExtensions
|
||||||
{
|
{
|
||||||
public static bool RenameMod( this ModManager manager, string newName, ModData mod )
|
public static bool RenameMod( this ModManager manager, string newName, ModData mod )
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ namespace Penumbra.UI.Custom
|
||||||
var itemWidth = ImGui.CalcItemWidth();
|
var itemWidth = ImGui.CalcItemWidth();
|
||||||
ImGui.PushItemWidth( Math.Max( 0f, itemWidth - frameHeight ) );
|
ImGui.PushItemWidth( Math.Max( 0f, itemWidth - frameHeight ) );
|
||||||
|
|
||||||
labelStack.Add( ( labelMin, labelMax ) );
|
LabelStack.Add( ( labelMin, labelMax ) );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,8 +111,8 @@ namespace Penumbra.UI.Custom
|
||||||
|
|
||||||
var itemMin = ImGui.GetItemRectMin();
|
var itemMin = ImGui.GetItemRectMin();
|
||||||
var itemMax = ImGui.GetItemRectMax();
|
var itemMax = ImGui.GetItemRectMax();
|
||||||
var (currentLabelMin, currentLabelMax) = labelStack[ labelStack.Count - 1 ];
|
var (currentLabelMin, currentLabelMax) = LabelStack[ LabelStack.Count - 1 ];
|
||||||
labelStack.RemoveAt( labelStack.Count - 1 );
|
LabelStack.RemoveAt( LabelStack.Count - 1 );
|
||||||
|
|
||||||
var halfFrame = new Vector2( frameHeight / 8, frameHeight / 2 );
|
var halfFrame = new Vector2( frameHeight / 8, frameHeight / 2 );
|
||||||
currentLabelMin.X -= itemSpacing.X;
|
currentLabelMin.X -= itemSpacing.X;
|
||||||
|
|
@ -143,6 +143,6 @@ namespace Penumbra.UI.Custom
|
||||||
|
|
||||||
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
||||||
|
|
||||||
private static readonly List< (Vector2, Vector2) > labelStack = new();
|
private static readonly List< (Vector2, Vector2) > LabelStack = new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,8 +76,13 @@ namespace Penumbra.UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var directory = _texToolsImport?.ExtractedDirectory;
|
||||||
_texToolsImport = null;
|
_texToolsImport = null;
|
||||||
_base.ReloadMods();
|
_base.ReloadMods();
|
||||||
|
if( directory != null )
|
||||||
|
{
|
||||||
|
_base._menu.InstalledTab.Selector.SelectModByDir( directory.Name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
_base = ui;
|
_base = ui;
|
||||||
_modNamesLower = Array.Empty< string >();
|
_modNamesLower = Array.Empty< string >();
|
||||||
_modManager = Service<ModManager>.Get();
|
_modManager = Service< ModManager >.Get();
|
||||||
ResetModNamesLower();
|
ResetModNamesLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue