diff --git a/Penumbra.Api b/Penumbra.Api index cfc51714..b28288ee 160000 --- a/Penumbra.Api +++ b/Penumbra.Api @@ -1 +1 @@ -Subproject commit cfc51714f74cae93608bc507775a9580cd1801de +Subproject commit b28288ee9668425f49f41cba88e8dc417ad62aff diff --git a/Penumbra/Api/IpcTester.cs b/Penumbra/Api/IpcTester.cs index aea95156..380b741c 100644 --- a/Penumbra/Api/IpcTester.cs +++ b/Penumbra/Api/IpcTester.cs @@ -484,7 +484,9 @@ public class IpcTester : IDisposable private DateTimeOffset _lastResolvedGamePathTime = DateTimeOffset.MaxValue; private string _currentDrawObjectString = string.Empty; private IntPtr _currentDrawObject = IntPtr.Zero; - private int _currentCutsceneActor = 0; + private int _currentCutsceneActor; + private int _currentCutsceneParent; + private PenumbraApiEc _cutsceneError = PenumbraApiEc.Success; public GameState(DalamudPluginInterface pi) { @@ -507,7 +509,14 @@ public class IpcTester : IDisposable ? tmp : IntPtr.Zero; - ImGui.InputInt("Cutscene Actor", ref _currentCutsceneActor, 0); + ImGui.InputInt("Cutscene Actor", ref _currentCutsceneActor, 0); + ImGui.InputInt("Cutscene Parent", ref _currentCutsceneParent, 0); + if (_cutsceneError is not PenumbraApiEc.Success) + { + ImGui.SameLine(); + ImGui.TextUnformatted("Invalid Argument on last Call"); + } + using var table = ImRaii.Table(string.Empty, 3, ImGuiTableFlags.SizingFixedFit); if (!table) return; @@ -526,6 +535,10 @@ public class IpcTester : IDisposable DrawIntro(Ipc.GetCutsceneParentIndex.Label, "Cutscene Parent"); ImGui.TextUnformatted(Ipc.GetCutsceneParentIndex.Subscriber(_pi).Invoke(_currentCutsceneActor).ToString()); + DrawIntro(Ipc.SetCutsceneParentIndex.Label, "Cutscene Parent"); + if (ImGui.Button("Set Parent")) + _cutsceneError = Ipc.SetCutsceneParentIndex.Subscriber(_pi).Invoke(_currentCutsceneActor, _currentCutsceneParent); + DrawIntro(Ipc.CreatingCharacterBase.Label, "Last Drawobject created"); if (_lastCreatedGameObjectTime < DateTimeOffset.Now) ImGui.TextUnformatted(_lastCreatedDrawObject != IntPtr.Zero diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index 2a7a9bfb..04c0499b 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -600,6 +600,15 @@ public class PenumbraApi : IDisposable, IPenumbraApi return _cutsceneService.GetParentIndex(actorIdx); } + public PenumbraApiEc SetCutsceneParentIndex(int copyIdx, int newParentIdx) + { + CheckInitialized(); + if (_cutsceneService.SetParentIndex(copyIdx, newParentIdx)) + return PenumbraApiEc.Success; + + return PenumbraApiEc.InvalidArgument; + } + public IList<(string, string)> GetModList() { CheckInitialized(); diff --git a/Penumbra/Api/PenumbraIpcProviders.cs b/Penumbra/Api/PenumbraIpcProviders.cs index 1df90dd9..d478b675 100644 --- a/Penumbra/Api/PenumbraIpcProviders.cs +++ b/Penumbra/Api/PenumbraIpcProviders.cs @@ -47,6 +47,7 @@ public class PenumbraIpcProviders : IDisposable // Game State internal readonly FuncProvider GetDrawObjectInfo; internal readonly FuncProvider GetCutsceneParentIndex; + internal readonly FuncProvider SetCutsceneParentIndex; internal readonly EventProvider CreatingCharacterBase; internal readonly EventProvider CreatedCharacterBase; internal readonly EventProvider GameObjectResourcePathResolved; @@ -171,6 +172,7 @@ public class PenumbraIpcProviders : IDisposable // Game State GetDrawObjectInfo = Ipc.GetDrawObjectInfo.Provider(pi, Api.GetDrawObjectInfo); GetCutsceneParentIndex = Ipc.GetCutsceneParentIndex.Provider(pi, Api.GetCutsceneParentIndex); + SetCutsceneParentIndex = Ipc.SetCutsceneParentIndex.Provider(pi, Api.SetCutsceneParentIndex); CreatingCharacterBase = Ipc.CreatingCharacterBase.Provider(pi, () => Api.CreatingCharacterBase += CreatingCharacterBaseEvent, () => Api.CreatingCharacterBase -= CreatingCharacterBaseEvent); @@ -293,6 +295,7 @@ public class PenumbraIpcProviders : IDisposable // Game State GetDrawObjectInfo.Dispose(); GetCutsceneParentIndex.Dispose(); + SetCutsceneParentIndex.Dispose(); CreatingCharacterBase.Dispose(); CreatedCharacterBase.Dispose(); GameObjectResourcePathResolved.Dispose(); diff --git a/Penumbra/Interop/PathResolving/CutsceneService.cs b/Penumbra/Interop/PathResolving/CutsceneService.cs index 85944d74..89b9f917 100644 --- a/Penumbra/Interop/PathResolving/CutsceneService.cs +++ b/Penumbra/Interop/PathResolving/CutsceneService.cs @@ -56,6 +56,24 @@ public sealed class CutsceneService : IService, IDisposable public int GetParentIndex(int idx) => GetParentIndex((ushort)idx); + public bool SetParentIndex(int copyIdx, int parentIdx) + { + if (copyIdx is < CutsceneStartIdx or >= CutsceneEndIdx) + return false; + + if (parentIdx is < -1 or >= CutsceneEndIdx) + return false; + + if (_objects.GetObjectAddress(copyIdx) == nint.Zero) + return false; + + if (parentIdx != -1 && _objects.GetObjectAddress(parentIdx) == nint.Zero) + return false; + + _copiedCharacters[copyIdx - CutsceneStartIdx] = (short)parentIdx; + return true; + } + public short GetParentIndex(ushort idx) { if (idx is >= CutsceneStartIdx and < CutsceneEndIdx)