From 4acf78b0dfdee9d626f554c71b07a8891206459c Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Thu, 10 Apr 2025 20:17:58 +0200 Subject: [PATCH] fix gpose world stuff --- .../Services/CharaData/CharaDataManager.cs | 53 +++++++++++-------- MareSynchronos/Services/DalamudUtilService.cs | 12 ++++- MareSynchronos/UI/CharaDataHubUi.cs | 6 +-- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/MareSynchronos/Services/CharaData/CharaDataManager.cs b/MareSynchronos/Services/CharaData/CharaDataManager.cs index 18a30fc..94f6e1a 100644 --- a/MareSynchronos/Services/CharaData/CharaDataManager.cs +++ b/MareSynchronos/Services/CharaData/CharaDataManager.cs @@ -127,17 +127,18 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { return UiBlockingComputation = DataApplicationTask = Task.Run(async () => { - var charaName = await _dalamudUtilService.RunOnFrameworkThread(() => _dalamudUtilService.GposeTargetGameObject?.Name.TextValue).ConfigureAwait(false) - ?? string.Empty; + var obj = await _dalamudUtilService.GetGposeTargetGameObjectAsync().ConfigureAwait(false); + var charaName = obj?.Name.TextValue ?? string.Empty; if (string.IsNullOrEmpty(charaName)) return; await ApplyCharaData(dataMetaInfoDto, charaName).ConfigureAwait(false); }); } - public void ApplyOwnDataToGposeTarget(CharaDataFullExtendedDto dataDto) + public async Task ApplyOwnDataToGposeTarget(CharaDataFullExtendedDto dataDto) { - var charaName = _dalamudUtilService.GposeTargetGameObject?.Name.TextValue ?? string.Empty; + var chara = await _dalamudUtilService.GetGposeTargetGameObjectAsync().ConfigureAwait(false); + var charaName = chara?.Name.TextValue ?? string.Empty; CharaDataDownloadDto downloadDto = new(dataDto.Id, dataDto.Uploader) { CustomizeData = dataDto.CustomizeData, @@ -164,7 +165,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { return UiBlockingComputation = Task.Run(async () => { - if (string.IsNullOrEmpty(pose.PoseData) || !CanApplyInGpose(out _)) return; + if (string.IsNullOrEmpty(pose.PoseData) || !(await CanApplyInGpose().ConfigureAwait(false)).CanApply) return; var gposeChara = await _dalamudUtilService.GetGposeCharacterFromObjectTableByNameAsync(targetName, true).ConfigureAwait(false); if (gposeChara == null) return; @@ -179,9 +180,11 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { return UiBlockingComputation = Task.Run(async () => { - if (CanApplyInGpose(out var chara)) + var apply = await CanApplyInGpose().ConfigureAwait(false); + + if (apply.CanApply) { - await ApplyPoseData(pose, chara).ConfigureAwait(false); + await ApplyPoseData(pose, apply.TargetName).ConfigureAwait(false); } }); } @@ -190,7 +193,8 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { return UiBlockingComputation = Task.Run(async () => { - if (pose.WorldData == default || !CanApplyInGpose(out _)) return; + var apply = await CanApplyInGpose().ConfigureAwait(false); + if (pose.WorldData == default || !(await CanApplyInGpose().ConfigureAwait(false)).CanApply) return; var gposeChara = await _dalamudUtilService.GetGposeCharacterFromObjectTableByNameAsync(targetName, true).ConfigureAwait(false); if (gposeChara == null) return; @@ -206,9 +210,10 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { return UiBlockingComputation = Task.Run(async () => { - if (CanApplyInGpose(out var chara)) + var apply = await CanApplyInGpose().ConfigureAwait(false); + if (apply.CanApply) { - await ApplyPoseData(pose, chara).ConfigureAwait(false); + await ApplyPoseData(pose, apply.TargetName).ConfigureAwait(false); } }); } @@ -239,19 +244,21 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase }); } - public bool CanApplyInGpose(out string targetName) + public async Task<(bool CanApply, string TargetName)> CanApplyInGpose() { - bool canApply = _dalamudUtilService.IsInGpose && _dalamudUtilService.GposeTargetGameObject != null - && _dalamudUtilService.GposeTargetGameObject.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player; + var obj = await _dalamudUtilService.GetGposeTargetGameObjectAsync().ConfigureAwait(false); + string targetName = string.Empty; + bool canApply = _dalamudUtilService.IsInGpose && obj != null + && obj.ObjectKind == Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player; if (canApply) { - targetName = _dalamudUtilService.GposeTargetGameObject!.Name.TextValue; + targetName = obj!.Name.TextValue; } else { targetName = "Invalid Target"; } - return canApply; + return (canApply, targetName); } public void CancelDataApplication() @@ -483,11 +490,12 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase }); } - public void McdfApplyToGposeTarget() + public async Task McdfApplyToGposeTarget() { - if (CanApplyInGpose(out string target)) + var apply = await CanApplyInGpose().ConfigureAwait(false); + if (apply.CanApply) { - McdfApplyToTarget(target); + McdfApplyToTarget(apply.TargetName); } } @@ -681,7 +689,7 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase _dalamudUtilService.GposeTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)newActor.Address; } - McdfApplyToGposeTarget(); + await McdfApplyToGposeTarget().ConfigureAwait(false); }); } @@ -698,10 +706,11 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase { UiBlockingComputation = Task.Run(async () => { - if (CanApplyInGpose(out var gposeTarget)) + var apply = await CanApplyInGpose().ConfigureAwait(false); + if (apply.CanApply) { - await ApplyPoseData(value, gposeTarget).ConfigureAwait(false); - await ApplyWorldDataToTarget(value, gposeTarget).ConfigureAwait(false); + await ApplyPoseData(value, apply.TargetName).ConfigureAwait(false); + await ApplyWorldDataToTarget(value, apply.TargetName).ConfigureAwait(false); } }); } diff --git a/MareSynchronos/Services/DalamudUtilService.cs b/MareSynchronos/Services/DalamudUtilService.cs index 6e95a56..3b0bead 100644 --- a/MareSynchronos/Services/DalamudUtilService.cs +++ b/MareSynchronos/Services/DalamudUtilService.cs @@ -152,7 +152,17 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber get => TargetSystem.Instance()->GPoseTarget; set => TargetSystem.Instance()->GPoseTarget = value; } - public unsafe Dalamud.Game.ClientState.Objects.Types.IGameObject? GposeTargetGameObject => GposeTarget == null ? null : _objectTable[GposeTarget->ObjectIndex]; + + private unsafe bool HasGposeTarget => GposeTarget != null; + private unsafe int GPoseTargetIdx => !HasGposeTarget ? -1 : GposeTarget->ObjectIndex; + + public async Task GetGposeTargetGameObjectAsync() + { + if (!HasGposeTarget) + return null; + + return await _framework.RunOnFrameworkThread(() => _objectTable[GPoseTargetIdx]).ConfigureAwait(true); + } public bool IsAnythingDrawing { get; private set; } = false; public bool IsInCutscene { get; private set; } = false; public bool IsInGpose { get; private set; } = false; diff --git a/MareSynchronos/UI/CharaDataHubUi.cs b/MareSynchronos/UI/CharaDataHubUi.cs index 0ec9422..6150375 100644 --- a/MareSynchronos/UI/CharaDataHubUi.cs +++ b/MareSynchronos/UI/CharaDataHubUi.cs @@ -161,7 +161,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase UpdateFilteredFavorites(); } - _hasValidGposeTarget = _charaDataManager.CanApplyInGpose(out _gposeTarget); + (_hasValidGposeTarget, _gposeTarget) = _charaDataManager.CanApplyInGpose().GetAwaiter().GetResult(); if (!_charaDataManager.BrioAvailable) { @@ -369,7 +369,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase UiSharedService.AttachToolTip($"Target the GPose Character {CharaName(actor.Name.TextValue)}"); ImGui.AlignTextToFramePadding(); var pos = ImGui.GetCursorPosX(); - using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen, actor.Address == (_dalamudUtilService.GposeTargetGameObject?.Address ?? nint.Zero))) + using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.HealerGreen, actor.Address == (_dalamudUtilService.GetGposeTargetGameObjectAsync().GetAwaiter().GetResult()?.Address ?? nint.Zero))) { ImGui.TextUnformatted(CharaName(actor.Name.TextValue)); } @@ -818,7 +818,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase { if (_uiSharedService.IconTextButton(FontAwesomeIcon.ArrowRight, "Apply")) { - _charaDataManager.McdfApplyToGposeTarget(); + _ = _charaDataManager.McdfApplyToGposeTarget(); } UiSharedService.AttachToolTip($"Apply to {_gposeTarget}"); ImGui.SameLine();