diff --git a/Penumbra/Interop/Services/GameEventManager.cs b/Penumbra/Interop/Services/GameEventManager.cs index 59714ff0..d11b7159 100644 --- a/Penumbra/Interop/Services/GameEventManager.cs +++ b/Penumbra/Interop/Services/GameEventManager.cs @@ -24,6 +24,10 @@ public unsafe class GameEventManager : IDisposable public GameEventManager(IGameInteropProvider interop) { interop.InitializeFromAttributes(this); + + _copyCharacterHook = + interop.HookFromAddress((nint)CharacterSetup.MemberFunctionPointers.CopyFromCharacter, CopyCharacterDetour); + _characterDtorHook.Enable(); _copyCharacterHook.Enable(); _resourceHandleDestructorHook.Enable(); @@ -78,19 +82,20 @@ public unsafe class GameEventManager : IDisposable #region Copy Character - private delegate ulong CopyCharacterDelegate(GameObject* target, GameObject* source, uint unk); + private delegate ulong CopyCharacterDelegate(CharacterSetup* target, GameObject* source, uint unk); - [Signature(Sigs.CopyCharacter, DetourName = nameof(CopyCharacterDetour))] - private readonly Hook _copyCharacterHook = null!; + private readonly Hook _copyCharacterHook; - private ulong CopyCharacterDetour(GameObject* target, GameObject* source, uint unk) + private ulong CopyCharacterDetour(CharacterSetup* target, GameObject* source, uint unk) { + // TODO: update when CS updated. + var character = ((Character**)target)[1]; if (CopyCharacter != null) foreach (var subscriber in CopyCharacter.GetInvocationList()) { try { - ((CopyCharacterEvent)subscriber).Invoke((Character*)target, (Character*)source); + ((CopyCharacterEvent)subscriber).Invoke(character, (Character*)source); } catch (Exception ex) { diff --git a/Penumbra/Interop/Services/RedrawService.cs b/Penumbra/Interop/Services/RedrawService.cs index 0864bb71..5cc493ad 100644 --- a/Penumbra/Interop/Services/RedrawService.cs +++ b/Penumbra/Interop/Services/RedrawService.cs @@ -1,4 +1,3 @@ -using Dalamud.Game; using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects.Enums; @@ -20,8 +19,10 @@ public unsafe partial class RedrawService public const int GPoseEndIdx = GPosePlayerIdx + GPoseSlots; private readonly string?[] _gPoseNames = new string?[GPoseSlots]; - private int _gPoseNameCounter = 0; - private bool _inGPose = false; + private int _gPoseNameCounter; + + private bool InGPose + => _clientState.IsGPosing; // VFuncs that disable and enable draw, used only for GPose actors. private static void DisableDraw(GameObject actor) @@ -33,10 +34,7 @@ public unsafe partial class RedrawService // Check whether we currently are in GPose. // Also clear the name list. private void SetGPose() - { - _inGPose = _objects[GPosePlayerIdx] != null; - _gPoseNameCounter = 0; - } + => _gPoseNameCounter = 0; private static bool IsGPoseActor(int idx) => idx is >= GPosePlayerIdx and < GPoseEndIdx; @@ -50,7 +48,7 @@ public unsafe partial class RedrawService private bool FindCorrectActor(int idx, out GameObject? obj) { obj = _objects[idx]; - if (!_inGPose || obj == null || IsGPoseActor(idx)) + if (!InGPose || obj == null || IsGPoseActor(idx)) return false; var name = obj.Name.ToString(); @@ -100,10 +98,11 @@ public unsafe partial class RedrawService public sealed unsafe partial class RedrawService : IDisposable { - private readonly IFramework _framework; + private readonly IFramework _framework; private readonly IObjectTable _objects; private readonly ITargetManager _targets; - private readonly ICondition _conditions; + private readonly ICondition _conditions; + private readonly IClientState _clientState; private readonly List _queue = new(100); private readonly List _afterGPoseQueue = new(GPoseSlots); @@ -111,12 +110,13 @@ public sealed unsafe partial class RedrawService : IDisposable public event GameObjectRedrawnDelegate? GameObjectRedrawn; - public RedrawService(IFramework framework, IObjectTable objects, ITargetManager targets, ICondition conditions) + public RedrawService(IFramework framework, IObjectTable objects, ITargetManager targets, ICondition conditions, IClientState clientState) { _framework = framework; _objects = objects; _targets = targets; _conditions = conditions; + _clientState = clientState; _framework.Update += OnUpdateEvent; } @@ -241,7 +241,7 @@ public sealed unsafe partial class RedrawService : IDisposable private void HandleAfterGPose() { - if (_afterGPoseQueue.Count == 0 || _inGPose) + if (_afterGPoseQueue.Count == 0 || InGPose) return; var numKept = 0;