mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Expand and name vfxWeaponHook to deal with more files.
This commit is contained in:
parent
5d96f789fe
commit
c86d2eded5
4 changed files with 32 additions and 21 deletions
|
|
@ -205,7 +205,7 @@ public class CollectionEditor
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
private void InvokeChange(ModCollection changedCollection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx)
|
private void InvokeChange(ModCollection changedCollection, ModSettingChange type, Mod? mod, int oldValue, int groupIdx)
|
||||||
{
|
{
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, changedCollection));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, changedCollection));
|
||||||
_communicator.ModSettingChanged.Invoke(changedCollection, type, mod, oldValue, groupIdx, false);
|
_communicator.ModSettingChanged.Invoke(changedCollection, type, mod, oldValue, groupIdx, false);
|
||||||
RecurseInheritors(changedCollection, type, mod, oldValue, groupIdx);
|
RecurseInheritors(changedCollection, type, mod, oldValue, groupIdx);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -194,14 +194,14 @@ public class CollectionStorage : IReadOnlyList<ModCollection>, IDisposable
|
||||||
var any = collection.UnusedSettings.Count > 0;
|
var any = collection.UnusedSettings.Count > 0;
|
||||||
((Dictionary<string, ModSettings.SavedSettings>)collection.UnusedSettings).Clear();
|
((Dictionary<string, ModSettings.SavedSettings>)collection.UnusedSettings).Clear();
|
||||||
if (any)
|
if (any)
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, collection));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, collection));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Remove a specific setting for not currently-installed mods from the given collection. </summary>
|
/// <summary> Remove a specific setting for not currently-installed mods from the given collection. </summary>
|
||||||
public void CleanUnavailableSetting(ModCollection collection, string? setting)
|
public void CleanUnavailableSetting(ModCollection collection, string? setting)
|
||||||
{
|
{
|
||||||
if (setting != null && ((Dictionary<string, ModSettings.SavedSettings>)collection.UnusedSettings).Remove(setting))
|
if (setting != null && ((Dictionary<string, ModSettings.SavedSettings>)collection.UnusedSettings).Remove(setting))
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, collection));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, collection));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -304,7 +304,7 @@ public class CollectionStorage : IReadOnlyList<ModCollection>, IDisposable
|
||||||
break;
|
break;
|
||||||
case ModPathChangeType.Moved:
|
case ModPathChangeType.Moved:
|
||||||
foreach (var collection in this.Where(collection => collection.Settings[mod.Index] != null))
|
foreach (var collection in this.Where(collection => collection.Settings[mod.Index] != null))
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, collection));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, collection));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -319,7 +319,7 @@ public class CollectionStorage : IReadOnlyList<ModCollection>, IDisposable
|
||||||
foreach (var collection in this)
|
foreach (var collection in this)
|
||||||
{
|
{
|
||||||
if (collection.Settings[mod.Index]?.HandleChanges(type, mod, groupIdx, optionIdx, movedToIdx) ?? false)
|
if (collection.Settings[mod.Index]?.HandleChanges(type, mod, groupIdx, optionIdx, movedToIdx) ?? false)
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, collection));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, collection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ public class InheritanceManager : IDisposable
|
||||||
var parent = inheritor.DirectlyInheritsFrom[idx];
|
var parent = inheritor.DirectlyInheritsFrom[idx];
|
||||||
((List<ModCollection>)inheritor.DirectlyInheritsFrom).RemoveAt(idx);
|
((List<ModCollection>)inheritor.DirectlyInheritsFrom).RemoveAt(idx);
|
||||||
((List<ModCollection>)parent.DirectParentOf).Remove(inheritor);
|
((List<ModCollection>)parent.DirectParentOf).Remove(inheritor);
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, inheritor));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, inheritor));
|
||||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||||
RecurseInheritanceChanges(inheritor);
|
RecurseInheritanceChanges(inheritor);
|
||||||
Penumbra.Log.Debug($"Removed {parent.AnonymizedName} from {inheritor.AnonymizedName} inheritances.");
|
Penumbra.Log.Debug($"Removed {parent.AnonymizedName} from {inheritor.AnonymizedName} inheritances.");
|
||||||
|
|
@ -100,7 +100,7 @@ public class InheritanceManager : IDisposable
|
||||||
if (!((List<ModCollection>)inheritor.DirectlyInheritsFrom).Move(from, to))
|
if (!((List<ModCollection>)inheritor.DirectlyInheritsFrom).Move(from, to))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, inheritor));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, inheritor));
|
||||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||||
RecurseInheritanceChanges(inheritor);
|
RecurseInheritanceChanges(inheritor);
|
||||||
Penumbra.Log.Debug($"Moved {inheritor.AnonymizedName}s inheritance {from} to {to}.");
|
Penumbra.Log.Debug($"Moved {inheritor.AnonymizedName}s inheritance {from} to {to}.");
|
||||||
|
|
@ -116,7 +116,7 @@ public class InheritanceManager : IDisposable
|
||||||
((List<ModCollection>)parent.DirectParentOf).Add(inheritor);
|
((List<ModCollection>)parent.DirectParentOf).Add(inheritor);
|
||||||
if (invokeEvent)
|
if (invokeEvent)
|
||||||
{
|
{
|
||||||
_saveService.DelaySave(new ModCollectionSave(_modStorage, inheritor));
|
_saveService.QueueSave(new ModCollectionSave(_modStorage, inheritor));
|
||||||
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
_communicator.CollectionInheritanceChanged.Invoke(inheritor, false);
|
||||||
RecurseInheritanceChanges(inheritor);
|
RecurseInheritanceChanges(inheritor);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
_unkMountAnimationHook.Enable();
|
_unkMountAnimationHook.Enable();
|
||||||
_unkParasolAnimationHook.Enable();
|
_unkParasolAnimationHook.Enable();
|
||||||
_dismountHook.Enable();
|
_dismountHook.Enable();
|
||||||
_vfxWeaponHook.Enable();
|
_apricotListenerSoundPlayHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HandleFiles(ResourceType type, Utf8GamePath _, out ResolveData resolveData)
|
public bool HandleFiles(ResourceType type, Utf8GamePath _, out ResolveData resolveData)
|
||||||
|
|
@ -106,7 +106,7 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
_unkMountAnimationHook.Dispose();
|
_unkMountAnimationHook.Dispose();
|
||||||
_unkParasolAnimationHook.Dispose();
|
_unkParasolAnimationHook.Dispose();
|
||||||
_dismountHook.Dispose();
|
_dismountHook.Dispose();
|
||||||
_vfxWeaponHook.Dispose();
|
_apricotListenerSoundPlayHook.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Characters load some of their voice lines or whatever with this function. </summary>
|
/// <summary> Characters load some of their voice lines or whatever with this function. </summary>
|
||||||
|
|
@ -364,23 +364,34 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
_animationLoadData.Value = last;
|
_animationLoadData.Value = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Signature("48 89 6C 24 ?? 41 54 41 56 41 57 48 81 EC", DetourName = nameof(VfxWeaponDetour))]
|
[Signature("48 89 6C 24 ?? 41 54 41 56 41 57 48 81 EC", DetourName = nameof(ApricotListenerSoundPlayDetour))]
|
||||||
private readonly Hook<VfxWeaponDelegate> _vfxWeaponHook = null!;
|
private readonly Hook<ApricotListenerSoundPlayDelegate> _apricotListenerSoundPlayHook = null!;
|
||||||
|
|
||||||
private delegate nint VfxWeaponDelegate(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6);
|
private delegate nint ApricotListenerSoundPlayDelegate(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6);
|
||||||
|
|
||||||
private nint VfxWeaponDetour(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6)
|
private nint ApricotListenerSoundPlayDetour(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6)
|
||||||
{
|
{
|
||||||
if (a6 == nint.Zero)
|
if (a6 == nint.Zero)
|
||||||
return _vfxWeaponHook!.Original(a1, a2, a3, a4, a5, a6);
|
return _apricotListenerSoundPlayHook!.Original(a1, a2, a3, a4, a5, a6);
|
||||||
|
|
||||||
var drawObject = ((DrawObject**)a6)[1];
|
|
||||||
if (drawObject == null)
|
|
||||||
return _vfxWeaponHook!.Original(a1, a2, a3, a4, a5, a6);
|
|
||||||
|
|
||||||
var last = _animationLoadData.Value;
|
var last = _animationLoadData.Value;
|
||||||
|
// a6 is some instance of Apricot.IInstanceListenner, in some cases we can obtain the associated caster via vfunc 1.
|
||||||
|
var gameObject = (*(delegate* unmanaged<nint, GameObject*>**)a6)[1](a6);
|
||||||
|
if (gameObject != null)
|
||||||
|
{
|
||||||
|
_animationLoadData.Value = _collectionResolver.IdentifyCollection(gameObject, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// for VfxListenner we can obtain the associated draw object as its first member,
|
||||||
|
// if the object has different type, drawObject will contain other values or garbage,
|
||||||
|
// but only be used in a dictionary pointer lookup, so this does not hurt.
|
||||||
|
var drawObject = ((DrawObject**)a6)[1];
|
||||||
|
if (drawObject != null)
|
||||||
_animationLoadData.Value = _collectionResolver.IdentifyCollection(drawObject, true);
|
_animationLoadData.Value = _collectionResolver.IdentifyCollection(drawObject, true);
|
||||||
var ret = _vfxWeaponHook!.Original(a1, a2, a3, a4, a5, a6);
|
}
|
||||||
|
|
||||||
|
var ret = _apricotListenerSoundPlayHook!.Original(a1, a2, a3, a4, a5, a6);
|
||||||
_animationLoadData.Value = last;
|
_animationLoadData.Value = last;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue