add LinkedModCollection to be able to retrospectively verify which gamepath was resolved for which game object

This commit is contained in:
Stanley Dimant 2022-09-03 16:09:31 +02:00 committed by Ottermandias
parent 07af64feed
commit dcdc6d1be1
16 changed files with 151 additions and 79 deletions

View file

@ -27,6 +27,7 @@ public delegate void CreatingCharacterBaseDelegate( IntPtr gameObject, ModCollec
IntPtr equipData );
public delegate void CreatedCharacterBaseDelegate( IntPtr gameObject, ModCollection collection, IntPtr drawObject );
public delegate void GameObjectResourceResolvedDelegate( IntPtr gameObject, string gamePath, string localPath );
public enum PenumbraApiEc
{
@ -79,6 +80,8 @@ public interface IPenumbraApi : IPenumbraApiBase
// so you can apply flag changes after finishing.
public event CreatedCharacterBaseDelegate? CreatedCharacterBase;
public event GameObjectResourceResolvedDelegate GameObjectResourceResolved;
// Queue redrawing of all actors of the given name with the given RedrawType.
public void RedrawObject( string name, RedrawType setting );

View file

@ -13,6 +13,7 @@ using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
@ -21,7 +22,7 @@ namespace Penumbra.Api;
public class PenumbraApi : IDisposable, IPenumbraApi
{
public (int, int) ApiVersion
=> ( 4, 12 );
=> ( 4, 13 );
private Penumbra? _penumbra;
private Lumina.GameData? _lumina;
@ -54,7 +55,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
public bool Valid
=> _penumbra != null;
public PenumbraApi( Penumbra penumbra )
public unsafe PenumbraApi( Penumbra penumbra )
{
_penumbra = penumbra;
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType()
@ -66,10 +67,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi
}
Penumbra.CollectionManager.CollectionChanged += SubscribeToNewCollections;
Penumbra.ResourceLoader.ResourceLoaded += OnResourceLoaded;
}
public void Dispose()
public unsafe void Dispose()
{
Penumbra.ResourceLoader.ResourceLoaded -= OnResourceLoaded;
Penumbra.CollectionManager.CollectionChanged -= SubscribeToNewCollections;
_penumbra = null;
_lumina = null;
@ -90,6 +93,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return Penumbra.Config.ModDirectory;
}
private unsafe void OnResourceLoaded( ResourceHandle* handle, Utf8GamePath originalPath, FullPath? manipulatedPath, LinkedModCollection? resolveData )
{
if( resolveData == null ) return;
GameObjectResourceResolved?.Invoke( resolveData.AssociatedGameObject, originalPath.ToString(), manipulatedPath?.ToString() ?? originalPath.ToString() );
}
public event Action< string, bool >? ModDirectoryChanged
{
add => Penumbra.ModManager.ModDirectoryChanged += value;
@ -103,6 +112,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
}
public event ChangedItemHover? ChangedItemTooltip;
public event GameObjectResourceResolvedDelegate? GameObjectResourceResolved;
public void RedrawObject( int tableIndex, RedrawType setting )
{
@ -232,7 +242,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
{
CheckInitialized();
var (obj, collection) = PathResolver.IdentifyDrawObject( drawObject );
return ( obj, collection.Name );
return ( obj, collection.ModCollection.Name );
}
public int GetCutsceneParentIndex( int actor )

View file

@ -283,6 +283,7 @@ public partial class PenumbraIpc
public const string LabelProviderReverseResolvePlayerPath = "Penumbra.ReverseResolvePlayerPath";
public const string LabelProviderCreatingCharacterBase = "Penumbra.CreatingCharacterBase";
public const string LabelProviderCreatedCharacterBase = "Penumbra.CreatedCharacterBase";
public const string LabelProviderGameObjectResourcePathResolved = "Penumbra.GameObjectResourcePathResolved";
internal ICallGateProvider< string, string >? ProviderResolveDefault;
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
@ -293,6 +294,7 @@ public partial class PenumbraIpc
internal ICallGateProvider< string, string[] >? ProviderReverseResolvePathPlayer;
internal ICallGateProvider< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >? ProviderCreatingCharacterBase;
internal ICallGateProvider< IntPtr, string, IntPtr, object? >? ProviderCreatedCharacterBase;
internal ICallGateProvider<IntPtr, string, string, object?>? ProviderGameObjectResourcePathResolved;
private void InitializeResolveProviders( DalamudPluginInterface pi )
{
@ -387,6 +389,21 @@ public partial class PenumbraIpc
{
PluginLog.Error( $"Error registering IPC provider for {LabelProviderCreatedCharacterBase}:\n{e}" );
}
try
{
ProviderGameObjectResourcePathResolved = pi.GetIpcProvider<IntPtr, string, string, object?>( LabelProviderGameObjectResourcePathResolved );
Api.GameObjectResourceResolved += GameObjectResourceResolvdedEvent;
}
catch( Exception e )
{
PluginLog.Error( $"Error registering IPC provider for {LabelProviderGameObjectResourcePathResolved}:\n{e}" );
}
}
private void GameObjectResourceResolvdedEvent( IntPtr gameObject, string gamePath, string localPath )
{
ProviderGameObjectResourcePathResolved?.SendMessage( gameObject, gamePath, localPath );
}
private void DisposeResolveProviders()