mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 20:54:16 +01:00
Do not associate timeline resources with characters in cutscenes.
This commit is contained in:
parent
306c2ffd10
commit
3f1d84343a
1 changed files with 15 additions and 9 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
|
|
@ -22,18 +23,20 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
private readonly CollectionResolver _collectionResolver;
|
private readonly CollectionResolver _collectionResolver;
|
||||||
private readonly DrawObjectState _drawObjectState;
|
private readonly DrawObjectState _drawObjectState;
|
||||||
private readonly CollectionResolver _resolver;
|
private readonly CollectionResolver _resolver;
|
||||||
|
private readonly Condition _conditions;
|
||||||
|
|
||||||
private readonly ThreadLocal<ResolveData> _animationLoadData = new(() => ResolveData.Invalid, true);
|
private readonly ThreadLocal<ResolveData> _animationLoadData = new(() => ResolveData.Invalid, true);
|
||||||
private readonly ThreadLocal<ResolveData> _characterSoundData = new(() => ResolveData.Invalid, true);
|
private readonly ThreadLocal<ResolveData> _characterSoundData = new(() => ResolveData.Invalid, true);
|
||||||
|
|
||||||
public AnimationHookService(PerformanceTracker performance, ObjectTable objects, CollectionResolver collectionResolver,
|
public AnimationHookService(PerformanceTracker performance, ObjectTable objects, CollectionResolver collectionResolver,
|
||||||
DrawObjectState drawObjectState, CollectionResolver resolver)
|
DrawObjectState drawObjectState, CollectionResolver resolver, Condition conditions)
|
||||||
{
|
{
|
||||||
_performance = performance;
|
_performance = performance;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_drawObjectState = drawObjectState;
|
_drawObjectState = drawObjectState;
|
||||||
_resolver = resolver;
|
_resolver = resolver;
|
||||||
|
_conditions = conditions;
|
||||||
|
|
||||||
SignatureHelper.Initialise(this);
|
SignatureHelper.Initialise(this);
|
||||||
|
|
||||||
|
|
@ -137,13 +140,17 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
private ulong LoadTimelineResourcesDetour(IntPtr timeline)
|
private ulong LoadTimelineResourcesDetour(IntPtr timeline)
|
||||||
{
|
{
|
||||||
using var performance = _performance.Measure(PerformanceType.TimelineResources);
|
using var performance = _performance.Measure(PerformanceType.TimelineResources);
|
||||||
var last = _animationLoadData.Value;
|
// Do not check timeline loading in cutscenes.
|
||||||
|
if (_conditions[ConditionFlag.OccupiedInCutSceneEvent] || _conditions[ConditionFlag.WatchingCutscene] || _conditions[ConditionFlag.WatchingCutscene78])
|
||||||
|
return _loadTimelineResourcesHook.Original(timeline);
|
||||||
|
|
||||||
|
var last = _animationLoadData.Value;
|
||||||
_animationLoadData.Value = GetDataFromTimeline(timeline);
|
_animationLoadData.Value = GetDataFromTimeline(timeline);
|
||||||
var ret = _loadTimelineResourcesHook.Original(timeline);
|
var ret = _loadTimelineResourcesHook.Original(timeline);
|
||||||
_animationLoadData.Value = last;
|
_animationLoadData.Value = last;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Probably used when the base idle animation gets loaded.
|
/// Probably used when the base idle animation gets loaded.
|
||||||
/// Make it aware of the correct collection to load the correct pap files.
|
/// Make it aware of the correct collection to load the correct pap files.
|
||||||
|
|
@ -287,17 +294,17 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Use timelines vfuncs to obtain the associated game object. </summary>
|
/// <summary> Use timelines vfuncs to obtain the associated game object. </summary>
|
||||||
private ResolveData GetDataFromTimeline(IntPtr timeline)
|
private ResolveData GetDataFromTimeline(nint timeline)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (timeline != IntPtr.Zero)
|
if (timeline != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
var getGameObjectIdx = ((delegate* unmanaged<IntPtr, int>**)timeline)[0][Offsets.GetGameObjectIdxVfunc];
|
var getGameObjectIdx = ((delegate* unmanaged<nint, int>**)timeline)[0][Offsets.GetGameObjectIdxVfunc];
|
||||||
var idx = getGameObjectIdx(timeline);
|
var idx = getGameObjectIdx(timeline);
|
||||||
if (idx >= 0 && idx < _objects.Length)
|
if (idx >= 0 && idx < _objects.Length)
|
||||||
{
|
{
|
||||||
var obj = (GameObject*)_objects.GetObjectAddress(idx);
|
var obj = (GameObject*)_objects.GetObjectAddress(idx);
|
||||||
return obj != null ? _collectionResolver.IdentifyCollection(obj, true) : ResolveData.Invalid;
|
return obj != null ? _collectionResolver.IdentifyCollection(obj, true) : ResolveData.Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +317,6 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
return ResolveData.Invalid;
|
return ResolveData.Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private delegate void UnkMountAnimationDelegate(DrawObject* drawObject, uint unk1, byte unk2, uint unk3);
|
private delegate void UnkMountAnimationDelegate(DrawObject* drawObject, uint unk1, byte unk2, uint unk3);
|
||||||
|
|
||||||
[Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 89 54 24", DetourName = nameof(UnkMountAnimationDetour))]
|
[Signature("48 89 5C 24 ?? 48 89 6C 24 ?? 89 54 24", DetourName = nameof(UnkMountAnimationDetour))]
|
||||||
|
|
@ -334,7 +340,7 @@ public unsafe class AnimationHookService : IDisposable
|
||||||
{
|
{
|
||||||
var last = _animationLoadData.Value;
|
var last = _animationLoadData.Value;
|
||||||
_animationLoadData.Value = _collectionResolver.IdentifyCollection(drawObject, true);
|
_animationLoadData.Value = _collectionResolver.IdentifyCollection(drawObject, true);
|
||||||
_unkParasolAnimationHook!.Original(drawObject, unk1);
|
_unkParasolAnimationHook.Original(drawObject, unk1);
|
||||||
_animationLoadData.Value = last;
|
_animationLoadData.Value = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue