private unsafe bool SubContextMenuOpeningImplementation(AgentContext *agentContext) { if (this.openSubContextMenu == null || this.selectedOpenSubContextMenuItem == null) { return(false); } // The important things to make this work are: // 1. Allocate a temporary sub context menu title. The value doesn't matter, we'll set it later. // 2. Context menu item count must equal 1 to tell the game there is enough space for the "< Return" item. // 3. Atk value count must equal the index of the first context menu item. // This is enough to keep the base data, but excludes the context menu item data. // We want to exclude context menu item data in this function because the game sometimes includes garbage items which can cause problems. // After this function, the game adds the "< Return" item, and THEN we add our own items after that. this.openSubContextMenu(agentContext); // Allocate a new 1 byte title. This is required for the game to render the titled context menu style. // The actual value doesn't matter at this point, we'll set it later. MemoryHelper.GameFree(ref this.currentSubContextMenuTitle, (ulong)IntPtr.Size); this.currentSubContextMenuTitle = MemoryHelper.GameAllocateUi(1); *(&(&agentContext->AgentContextInterface)->SubContextMenuTitle) = (byte *)this.currentSubContextMenuTitle; *(byte *)this.currentSubContextMenuTitle = 0; // Expect at least 1 context menu item. (&agentContext->Items->AtkValues)[0].UInt = 1; // Expect a title. This isn't needed by the game, it's needed by ContextMenuReaderWriter which uses this to check if it's a context menu (&agentContext->Items->AtkValues)[1].ChangeType(ValueType.String); (&agentContext->Items->AtkValues)[1].String = (byte *)0; ContextMenuReaderWriter contextMenuReaderWriter = new ContextMenuReaderWriter(&agentContext->AgentContextInterface, agentContext->Items->AtkValueCount, &agentContext->Items->AtkValues); *(&agentContext->Items->AtkValueCount) = (ushort)contextMenuReaderWriter.FirstContextMenuItemIndex; return(true); }
private unsafe bool SubContextMenuOpeningDetour(AgentContext *agentContext) { return(this.SubContextMenuOpeningImplementation(agentContext) || this.subContextMenuOpeningHook.Original(agentContext)); }