mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Some fixes.
This commit is contained in:
parent
8fd9569508
commit
abce14dfdd
8 changed files with 50 additions and 148 deletions
|
|
@ -72,25 +72,7 @@ public partial class ModCollection
|
|||
? c.Index
|
||||
: Default.Index
|
||||
: -1,
|
||||
CollectionType.Yourself => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.PlayerCharacter => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.NonPlayerCharacter => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Midlander => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Highlander => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Wildwood => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Duskwight => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Plainsfolk => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Dunesfolk => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.SeekerOfTheSun => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.KeeperOfTheMoon => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Seawolf => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Hellsguard => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Raen => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Xaela => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Helion => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Lost => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Rava => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
CollectionType.Veena => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
_ when collectionType.IsSpecial() => _specialCollections[ ( int )collectionType ]?.Index ?? Default.Index,
|
||||
_ => -1,
|
||||
};
|
||||
|
||||
|
|
@ -146,71 +128,30 @@ public partial class ModCollection
|
|||
// Create a special collection if it does not exist and set it to Empty.
|
||||
public bool CreateSpecialCollection( CollectionType collectionType )
|
||||
{
|
||||
switch( collectionType )
|
||||
if( !collectionType.IsSpecial() || _specialCollections[( int )collectionType] != null )
|
||||
{
|
||||
case CollectionType.Yourself:
|
||||
case CollectionType.PlayerCharacter:
|
||||
case CollectionType.NonPlayerCharacter:
|
||||
case CollectionType.Midlander:
|
||||
case CollectionType.Highlander:
|
||||
case CollectionType.Wildwood:
|
||||
case CollectionType.Duskwight:
|
||||
case CollectionType.Plainsfolk:
|
||||
case CollectionType.Dunesfolk:
|
||||
case CollectionType.SeekerOfTheSun:
|
||||
case CollectionType.KeeperOfTheMoon:
|
||||
case CollectionType.Seawolf:
|
||||
case CollectionType.Hellsguard:
|
||||
case CollectionType.Raen:
|
||||
case CollectionType.Xaela:
|
||||
case CollectionType.Helion:
|
||||
case CollectionType.Lost:
|
||||
case CollectionType.Rava:
|
||||
case CollectionType.Veena:
|
||||
if( _specialCollections[ ( int )collectionType ] != null )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_specialCollections[ ( int )collectionType ] = Empty;
|
||||
CollectionChanged.Invoke( collectionType, null, Empty, null );
|
||||
return true;
|
||||
default: return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
_specialCollections[ ( int )collectionType ] = Empty;
|
||||
CollectionChanged.Invoke( collectionType, null, Empty, null );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// Remove a special collection if it exists
|
||||
public void RemoveSpecialCollection( CollectionType collectionType )
|
||||
{
|
||||
switch( collectionType )
|
||||
if( !collectionType.IsSpecial() )
|
||||
{
|
||||
case CollectionType.Yourself:
|
||||
case CollectionType.PlayerCharacter:
|
||||
case CollectionType.NonPlayerCharacter:
|
||||
case CollectionType.Midlander:
|
||||
case CollectionType.Highlander:
|
||||
case CollectionType.Wildwood:
|
||||
case CollectionType.Duskwight:
|
||||
case CollectionType.Plainsfolk:
|
||||
case CollectionType.Dunesfolk:
|
||||
case CollectionType.SeekerOfTheSun:
|
||||
case CollectionType.KeeperOfTheMoon:
|
||||
case CollectionType.Seawolf:
|
||||
case CollectionType.Hellsguard:
|
||||
case CollectionType.Raen:
|
||||
case CollectionType.Xaela:
|
||||
case CollectionType.Helion:
|
||||
case CollectionType.Lost:
|
||||
case CollectionType.Rava:
|
||||
case CollectionType.Veena:
|
||||
var old = _specialCollections[ ( int )collectionType ];
|
||||
if( old != null )
|
||||
{
|
||||
_specialCollections[ ( int )collectionType ] = null;
|
||||
CollectionChanged.Invoke( collectionType, old, null, null );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
var old = _specialCollections[ ( int )collectionType ];
|
||||
if( old != null )
|
||||
{
|
||||
_specialCollections[ ( int )collectionType ] = null;
|
||||
CollectionChanged.Invoke( collectionType, old, null, null );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,22 +30,12 @@ public unsafe class CharacterUtility : IDisposable
|
|||
// The defines are set in the project configuration.
|
||||
public static readonly int[] RelevantIndices
|
||||
= Array.Empty< int >()
|
||||
#if USE_EQP
|
||||
.Append( Structs.CharacterUtility.EqpIdx )
|
||||
#endif
|
||||
#if USE_GMP
|
||||
.Append( Structs.CharacterUtility.GmpIdx )
|
||||
#endif
|
||||
#if USE_EQDP
|
||||
.Concat( Enumerable.Range( Structs.CharacterUtility.EqdpStartIdx, Structs.CharacterUtility.NumEqdpFiles )
|
||||
.Where( i => i != 17 ) ) // TODO: Female Hrothgar
|
||||
#endif
|
||||
#if USE_CMP
|
||||
.Append( Structs.CharacterUtility.HumanCmpIdx )
|
||||
#endif
|
||||
#if USE_EST
|
||||
.Concat( Enumerable.Range( Structs.CharacterUtility.FaceEstIdx, 4 ) )
|
||||
#endif
|
||||
.ToArray();
|
||||
|
||||
public static readonly int[] ReverseIndices
|
||||
|
|
|
|||
|
|
@ -26,10 +26,8 @@ public unsafe class MetaFileManager : IDisposable
|
|||
|
||||
// Allocate in the games space for file storage.
|
||||
// We only need this if using any meta file.
|
||||
#if USE_IMC || USE_CMP || USE_EQDP || USE_EQP || USE_EST || USE_GMP
|
||||
[Signature( "E8 ?? ?? ?? ?? 41 B9 ?? ?? ?? ?? 4C 8B C0" )]
|
||||
public IntPtr GetFileSpaceAddress;
|
||||
#endif
|
||||
public IMemorySpace* GetFileSpace()
|
||||
=> ( ( delegate* unmanaged< IMemorySpace* > )GetFileSpaceAddress )();
|
||||
|
||||
|
|
@ -41,10 +39,8 @@ public unsafe class MetaFileManager : IDisposable
|
|||
|
||||
|
||||
// We only need this for IMC files, since we need to hook their cleanup function.
|
||||
#if USE_IMC
|
||||
[Signature( "48 8D 05 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 89 03", ScanType = ScanType.StaticAddress )]
|
||||
public IntPtr* DefaultResourceHandleVTable;
|
||||
#endif
|
||||
|
||||
public delegate void ClearResource( ResourceHandle* resource );
|
||||
public Hook< ClearResource > ClearDefaultResourceHook = null!;
|
||||
|
|
@ -67,7 +63,6 @@ public unsafe class MetaFileManager : IDisposable
|
|||
}
|
||||
|
||||
// Called when a new IMC is manipulated to store its data.
|
||||
[Conditional( "USE_IMC" )]
|
||||
public void AddImcFile( ResourceHandle* resource, IntPtr data, int length )
|
||||
{
|
||||
PluginLog.Debug( "Storing data 0x{Data:X} of Length {Length} for {$Name:l} (0x{Resource:X}).", ( ulong )data, length,
|
||||
|
|
@ -76,14 +71,12 @@ public unsafe class MetaFileManager : IDisposable
|
|||
}
|
||||
|
||||
// Initialize the hook at VFunc 25, which is called when default resources (and IMC resources do not overwrite it) destroy their data.
|
||||
[Conditional( "USE_IMC" )]
|
||||
private void InitImc()
|
||||
{
|
||||
ClearDefaultResourceHook = new Hook< ClearResource >( DefaultResourceHandleVTable[ 25 ], ClearDefaultResourceDetour );
|
||||
ClearDefaultResourceHook.Enable();
|
||||
}
|
||||
|
||||
[Conditional( "USE_IMC" )]
|
||||
private void DisposeImc()
|
||||
{
|
||||
ClearDefaultResourceHook.Disable();
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ public unsafe partial class PathResolver
|
|||
// Housing Retainers
|
||||
if( Penumbra.Config.UseDefaultCollectionForRetainers
|
||||
&& gameObject->ObjectKind == ( byte )ObjectKind.EventNpc
|
||||
&& gameObject->DataID is 1011832 or 1011021 ) // cf. "E8 ?? ?? ?? ?? 0F B6 F8 88 45"
|
||||
&& gameObject->DataID is 1011832 or 1011021 ) // cf. "E8 ?? ?? ?? ?? 0F B6 F8 88 45", male or female retainer
|
||||
{
|
||||
return Penumbra.CollectionManager.Default;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,19 +127,11 @@ public unsafe partial class PathResolver
|
|||
|
||||
private void EnableMetaHooks()
|
||||
{
|
||||
#if USE_EQP
|
||||
GetEqpIndirectHook?.Enable();
|
||||
#endif
|
||||
#if USE_EQP || USE_EQDP
|
||||
UpdateModelsHook?.Enable();
|
||||
OnModelLoadCompleteHook?.Enable();
|
||||
#endif
|
||||
#if USE_GMP
|
||||
SetupVisorHook?.Enable();
|
||||
#endif
|
||||
#if USE_CMP
|
||||
RspSetupCharacterHook?.Enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void DisableMetaHooks()
|
||||
|
|
@ -196,30 +188,23 @@ public unsafe partial class PathResolver
|
|||
|
||||
public static MetaChanger ChangeEqp( ModCollection collection )
|
||||
{
|
||||
#if USE_EQP
|
||||
collection.SetEqpFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Eqp );
|
||||
#else
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
#endif
|
||||
}
|
||||
|
||||
public static MetaChanger ChangeEqp( PathResolver resolver, IntPtr drawObject )
|
||||
{
|
||||
#if USE_EQP
|
||||
var collection = resolver.GetCollection( drawObject );
|
||||
if( collection != null )
|
||||
{
|
||||
return ChangeEqp( collection );
|
||||
}
|
||||
#endif
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
}
|
||||
|
||||
// We only need to change anything if it is actually equipment here.
|
||||
public static MetaChanger ChangeEqdp( PathResolver resolver, IntPtr drawObject, uint modelType )
|
||||
{
|
||||
#if USE_EQDP
|
||||
if( modelType < 10 )
|
||||
{
|
||||
var collection = resolver.GetCollection( drawObject );
|
||||
|
|
@ -228,43 +213,34 @@ public unsafe partial class PathResolver
|
|||
return ChangeEqdp( collection );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
}
|
||||
|
||||
public static MetaChanger ChangeEqdp( ModCollection collection )
|
||||
{
|
||||
#if USE_EQDP
|
||||
collection.SetEqdpFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Eqdp );
|
||||
#else
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
#endif
|
||||
}
|
||||
|
||||
public static MetaChanger ChangeGmp( PathResolver resolver, IntPtr drawObject )
|
||||
{
|
||||
#if USE_GMP
|
||||
var collection = resolver.GetCollection( drawObject );
|
||||
if( collection != null )
|
||||
{
|
||||
collection.SetGmpFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Gmp );
|
||||
}
|
||||
#endif
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
}
|
||||
|
||||
public static MetaChanger ChangeEst( PathResolver resolver, IntPtr drawObject )
|
||||
{
|
||||
#if USE_EST
|
||||
var collection = resolver.GetCollection( drawObject );
|
||||
if( collection != null )
|
||||
{
|
||||
collection.SetEstFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Est );
|
||||
}
|
||||
#endif
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
}
|
||||
|
||||
|
|
@ -273,13 +249,11 @@ public unsafe partial class PathResolver
|
|||
if( resolver.LastGameObject != null )
|
||||
{
|
||||
collection = IdentifyCollection( resolver.LastGameObject );
|
||||
#if USE_CMP
|
||||
if( collection != Penumbra.CollectionManager.Default && collection.HasCache )
|
||||
{
|
||||
collection.SetCmpFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Rsp );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -291,14 +265,12 @@ public unsafe partial class PathResolver
|
|||
|
||||
public static MetaChanger ChangeCmp( PathResolver resolver, IntPtr drawObject )
|
||||
{
|
||||
#if USE_CMP
|
||||
var collection = resolver.GetCollection( drawObject );
|
||||
if( collection != null )
|
||||
{
|
||||
collection.SetCmpFiles();
|
||||
return new MetaChanger( MetaManipulation.Type.Rsp );
|
||||
}
|
||||
#endif
|
||||
return new MetaChanger( MetaManipulation.Type.Unknown );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,32 +87,31 @@ public partial class MetaManager
|
|||
|
||||
public bool RevertMod( ImcManipulation m )
|
||||
{
|
||||
#if USE_IMC
|
||||
if( _imcManipulations.Remove( m ) )
|
||||
if( !_imcManipulations.Remove( m ) )
|
||||
{
|
||||
var path = m.GamePath();
|
||||
if( !_imcFiles.TryGetValue( path, out var file ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var def = ImcFile.GetDefault( path, m.EquipSlot, m.Variant, out _ );
|
||||
var manip = m with { Entry = def };
|
||||
if( !manip.Apply( file ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var fullPath = CreateImcPath( path );
|
||||
if( _collection.HasCache )
|
||||
{
|
||||
_collection.ForceFile( path, fullPath );
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
|
||||
var path = m.GamePath();
|
||||
if( !_imcFiles.TryGetValue( path, out var file ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var def = ImcFile.GetDefault( path, m.EquipSlot, m.Variant, out _ );
|
||||
var manip = m with { Entry = def };
|
||||
if( !manip.Apply( file ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var fullPath = CreateImcPath( path );
|
||||
if( _collection.HasCache )
|
||||
{
|
||||
_collection.ForceFile( path, fullPath );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DisposeImc()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using Penumbra.Mods;
|
|||
|
||||
namespace Penumbra.Meta.Manager;
|
||||
|
||||
public partial class MetaManager : IDisposable, IEnumerable<KeyValuePair<MetaManipulation, IMod>>
|
||||
public partial class MetaManager : IDisposable, IEnumerable< KeyValuePair< MetaManipulation, IMod > >
|
||||
{
|
||||
private readonly Dictionary< MetaManipulation, IMod > _manipulations = new();
|
||||
private readonly ModCollection _collection;
|
||||
|
|
@ -25,7 +25,7 @@ public partial class MetaManager : IDisposable, IEnumerable<KeyValuePair<MetaMan
|
|||
=> _manipulations.Keys;
|
||||
|
||||
|
||||
public IEnumerator<KeyValuePair<MetaManipulation, IMod>> GetEnumerator()
|
||||
public IEnumerator< KeyValuePair< MetaManipulation, IMod > > GetEnumerator()
|
||||
=> _manipulations.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
|
|
@ -135,6 +135,12 @@ public partial class MetaManager : IDisposable, IEnumerable<KeyValuePair<MetaMan
|
|||
};
|
||||
}
|
||||
|
||||
if( Penumbra.CollectionManager.Default == _collection )
|
||||
{
|
||||
SetFiles();
|
||||
Penumbra.ResidentResources.Reload();
|
||||
}
|
||||
|
||||
Penumbra.CharacterUtility.LoadingFinished -= ApplyStoredManipulations;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,7 +250,8 @@ public partial class ConfigWindow
|
|||
}
|
||||
|
||||
foreach( var collection in Penumbra.CollectionManager
|
||||
.Where( c => Penumbra.CollectionManager.Current.CheckValidInheritance( c ) == ModCollection.ValidInheritance.Valid ) )
|
||||
.Where( c => Penumbra.CollectionManager.Current.CheckValidInheritance( c ) == ModCollection.ValidInheritance.Valid )
|
||||
.OrderBy( c => c.Name ))
|
||||
{
|
||||
if( ImGui.Selectable( collection.Name, _newInheritance == collection ) )
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue