#pragma once #include #include struct IMenu; struct UIMessage { enum UI_MESSAGE_TYPE { kUpdate = 0, kShow = 1, kReshow = 2, kHide = 3, kForceHide = 4, kScaleformEvent = 6, // BSUIScaleformData kUserEvent = 7, // BSUIMessageData kInventoryUpdate = 8, // InventoryUpdateData kUserProfileChange = 9, kMUStatusChange = 10, kResumeCaching = 11, kUpdateController = 12, kChatterEvent = 13 }; BSFixedString menu; UI_MESSAGE_TYPE eType; uint32_t pad0C; void* data; bool isPooled; uint8_t pad19; uint16_t pad1A; uint32_t pad1C; }; class UI { public: static UI* Get(); bool GetMenuOpen(const BSFixedString& acName) const; void CloseAllMenus(); void DebugLogAllMenus(); IMenu* FindMenuByName(const BSFixedString& acName); BSFixedString* LookupMenuNameByInstance(IMenu* apMenu); public: using TCreate = IMenu*(UIMessage*); struct UIMenuEntry { IMenu* spMenu; // Actually a scaleform ptr TODO: reverse that stuff. TCreate* create; }; char pad_0[0x110]; // Too lazy to reverse inheritance for now. // All currently opened menus GameArray menuStack; // A map of name to the entry, the game will only create the menu instance // if the menu is opened, and frees it otherwise. creation::BSTHashMap menuMap; uint64_t spinlock; // These offsets are a bit unreliable. // // // char pad_2[0x18]; uint32_t numPausesGame; // 160 (= 0) += 1 if (imenu->flags & 0x00001) uint32_t numItemMenus; // 164 (= 0) += 1 if (imenu->flags & 0x02000) uint32_t numDisablePauseMenu; // 168 (= 0) += 1 if (imenu->flags & 0x00080) uint32_t numAllowSaving; // 16C (= 0) += 1 if (imenu->flags & 0x00800) uint32_t numDontHideCursorWhenTopmost; // 170 (= 0) += 1 if (imenu->flags & 0x04000) uint32_t numCustomRendering; // 174 (= 0) += 1 if (imenu->flags & 0x08000) uint32_t numApplicationMenus; // 178 (= 0) += 1 if (imenu->flags & 0x20000) bool modal; // 17C (= 0) = 1 if (imenu->flags & 0x00010) uint8_t pad17D; uint16_t pad17E; char pad_180[0x1C0 - 0x180]; bool menuSystemVisible; bool closingAllMenus; uint16_t pad1C2; uint32_t pad1C4; }; // intellisense is too dumb but the compiler knows. static_assert(sizeof(UI) == 0x1C8); static_assert(offsetof(UI, UI::numPausesGame) == 0x160);