Do not associate timeline resources with characters in cutscenes.

This commit is contained in:
Ottermandias 2023-06-17 01:24:49 +02:00
parent 306c2ffd10
commit 3f1d84343a

View file

@ -1,5 +1,6 @@
using System;
using System.Threading;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
@ -22,18 +23,20 @@ public unsafe class AnimationHookService : IDisposable
private readonly CollectionResolver _collectionResolver;
private readonly DrawObjectState _drawObjectState;
private readonly CollectionResolver _resolver;
private readonly Condition _conditions;
private readonly ThreadLocal<ResolveData> _animationLoadData = new(() => ResolveData.Invalid, true);
private readonly ThreadLocal<ResolveData> _characterSoundData = new(() => ResolveData.Invalid, true);
public AnimationHookService(PerformanceTracker performance, ObjectTable objects, CollectionResolver collectionResolver,
DrawObjectState drawObjectState, CollectionResolver resolver)
DrawObjectState drawObjectState, CollectionResolver resolver, Condition conditions)
{
_performance = performance;
_objects = objects;
_collectionResolver = collectionResolver;
_drawObjectState = drawObjectState;
_resolver = resolver;
_conditions = conditions;
SignatureHelper.Initialise(this);
@ -137,13 +140,17 @@ public unsafe class AnimationHookService : IDisposable
private ulong LoadTimelineResourcesDetour(IntPtr timeline)
{
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);
var ret = _loadTimelineResourcesHook.Original(timeline);
_animationLoadData.Value = last;
return ret;
}
/// <summary>
/// Probably used when the base idle animation gets loaded.
/// 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>
private ResolveData GetDataFromTimeline(IntPtr timeline)
private ResolveData GetDataFromTimeline(nint timeline)
{
try
{
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);
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;
}
}
@ -310,7 +317,6 @@ public unsafe class AnimationHookService : IDisposable
return ResolveData.Invalid;
}
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))]
@ -334,7 +340,7 @@ public unsafe class AnimationHookService : IDisposable
{
var last = _animationLoadData.Value;
_animationLoadData.Value = _collectionResolver.IdentifyCollection(drawObject, true);
_unkParasolAnimationHook!.Original(drawObject, unk1);
_unkParasolAnimationHook.Original(drawObject, unk1);
_animationLoadData.Value = last;
}