From ba7ea47ae017f9792ddda77b4ed7a05e4b3cbc1b Mon Sep 17 00:00:00 2001 From: momo5502 Date: Thu, 14 Jan 2016 15:29:39 +0100 Subject: [PATCH] Replacing the connect menu fully works now. --- src/Components/Modules/AssetHandler.cpp | 11 +++++ src/Components/Modules/AssetHandler.hpp | 2 + src/Components/Modules/Menus.cpp | 65 +++++++++++++++++++++---- src/Components/Modules/Menus.hpp | 3 ++ src/Game/Functions.hpp | 2 +- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 9bf98310..3e92aad4 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -181,6 +181,17 @@ namespace Components } } + Game::XAssetHeader AssetHandler::FindOriginalAsset(Game::XAssetType type, const char* filename) + { + Game::XAssetHeader header = { 0 }; + + AssetHandler::BypassState = true; + header = Game::DB_FindXAssetHeader(type, filename); + AssetHandler::BypassState = false; + + return header; + } + AssetHandler::AssetHandler() { // DB_FindXAssetHeader diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index 0d4d0370..930974d4 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -28,6 +28,8 @@ namespace Components static void ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder); static void ZoneMark(Game::XAsset asset, ZoneBuilder::Zone* builder); + static Game::XAssetHeader FindOriginalAsset(Game::XAssetType type, const char* filename); + private: static bool BypassState; diff --git a/src/Components/Modules/Menus.cpp b/src/Components/Modules/Menus.cpp index 322e099d..551d5c1b 100644 --- a/src/Components/Modules/Menus.cpp +++ b/src/Components/Modules/Menus.cpp @@ -455,16 +455,7 @@ namespace Components Game::XAssetHeader Menus::MenuLoad(Game::XAssetType type, const char* filename) { - Game::XAssetHeader header = { 0 }; - - header.menu = Menus::FindMenuByName(Game::uiContext, filename); - - if (!header.menu) - { - OutputDebugStringA("Oh snap!"); - } - - return header; + return { Menus::FindMenuByName(Game::uiContext, filename) }; } Game::XAssetHeader Menus::MenuFileLoad(Game::XAssetType type, const char* filename) @@ -510,6 +501,31 @@ namespace Components Game::UI_AddMenuList(dc, menuList, close); } + void Menus::RemoveFromStack(Game::UiContext *dc, Game::menuDef_t *menu) + { + // Search menu in stack + int i = 0; + for (; i < dc->menuCount; i++) + { + if (dc->Menus[i] == menu) + { + break; + } + } + + // Remove from stack + if (i < dc->menuCount) + { + for (; i < dc->menuCount - 1; i++) + { + dc->Menus[i] = dc->Menus[i + 1]; + } + + // Clear last menu + dc->Menus[--dc->menuCount] = 0; + } + } + Game::menuDef_t* Menus::FindMenuByName(Game::UiContext* dc, const char* name) { for (int i = 0; i < dc->menuCount; i++) @@ -531,6 +547,29 @@ namespace Components return nullptr; } + bool Menus::IsMenuVisible(Game::UiContext *dc, Game::menuDef_t *menu) + { + if (menu && menu->window.name) + { + if (std::string(menu->window.name) == "connect") // Check if we're supposed to draw the loadscreen + { + Game::menuDef_t* originalConnect = AssetHandler::FindOriginalAsset(Game::XAssetType::ASSET_TYPE_MENU, "connect").menu; + + if (originalConnect == menu) // Check if we draw the original loadscreen + { + if (Menus::MenuList.find("connect") != Menus::MenuList.end()) // Check if we have a custom loadscreen, to prevent drawing the original one ontop + { + Menus::RemoveFromStack(dc, menu); + return false; + } + } + } + } + + return Game::Menu_IsVisible(dc, menu); + } + + void Menus::Add(std::string menu) { Menus::CustomMenus.push_back(menu); @@ -547,6 +586,12 @@ namespace Components AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENU, Menus::MenuLoad); AssetHandler::OnFind(Game::XAssetType::ASSET_TYPE_MENUFILE, Menus::MenuFileLoad); + // Don't open connect menu + Utils::Hook::Nop(0x428E48, 5); + + // Intercept menu painting + Utils::Hook(0x4FFBDF, Menus::IsMenuVisible, HOOK_CALL).Install()->Quick(); + // Custom Menus_FindByName Utils::Hook(0x487240, Menus::FindMenuByName, HOOK_JUMP).Install()->Quick(); diff --git a/src/Components/Modules/Menus.hpp b/src/Components/Modules/Menus.hpp index 0db681e7..fe123b4f 100644 --- a/src/Components/Modules/Menus.hpp +++ b/src/Components/Modules/Menus.hpp @@ -47,6 +47,9 @@ namespace Components static void AddMenuListHook(Game::UiContext *dc, Game::MenuList *menuList, int close); static Game::menuDef_t* FindMenuByName(Game::UiContext* dc, const char* name); + static void RemoveFromStack(Game::UiContext *dc, Game::menuDef_t *menu); + + static bool IsMenuVisible(Game::UiContext *dc, Game::menuDef_t *menu); // Ugly! static int KeywordHash(char* key); diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index def955c3..edd5be31 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -148,7 +148,7 @@ namespace Game typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p); extern Menus_OpenByName_t Menus_OpenByName; - typedef int(__cdecl * Menu_IsVisible_t)(UiContext *dc, menuDef_t *menu); + typedef bool(__cdecl * Menu_IsVisible_t)(UiContext *dc, menuDef_t *menu); extern Menu_IsVisible_t Menu_IsVisible; typedef int(__cdecl * Menus_MenuIsInStack_t)(UiContext *dc, menuDef_t *menu);