2022-09-03 21:40:06 -04:00
|
|
|
#include <std_include.hpp>
|
|
|
|
#include "loader/component_loader.hpp"
|
|
|
|
|
|
|
|
#include "menus.hpp"
|
|
|
|
|
|
|
|
#include "game/game.hpp"
|
|
|
|
|
|
|
|
#include "console.hpp"
|
|
|
|
#include "command.hpp"
|
|
|
|
|
|
|
|
#include "utils/hook.hpp"
|
|
|
|
#include "utils/string.hpp"
|
|
|
|
|
|
|
|
namespace menus
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
namespace
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
std::string script_main_menu;
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
bool keys_bypass_menu()
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
const auto* cl_bypass_mouse_input = game::Dvar_FindVar("cl_bypassMouseInput");
|
|
|
|
if (cl_bypass_mouse_input && cl_bypass_mouse_input->current.enabled)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
return false;
|
|
|
|
}
|
2022-09-03 21:40:06 -04:00
|
|
|
|
|
|
|
game::XAssetHeader load_script_menu_internal(const char* menu)
|
|
|
|
{
|
|
|
|
const char* menu_file = utils::string::va("ui_mp/scriptmenus/%s.menu", menu);
|
|
|
|
return game::DB_FindXAssetHeader(game::ASSET_TYPE_MENUFILE, menu_file, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool load_script_menu(int client_num, const char* menu)
|
|
|
|
{
|
|
|
|
game::XAssetHeader asset = load_script_menu_internal(menu);
|
2022-11-09 19:38:53 -05:00
|
|
|
if (asset.data != nullptr)
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
game::UI_AddMenuList(game::ui_info_array, asset.data, 1);
|
2022-09-03 21:40:06 -04:00
|
|
|
return true;
|
|
|
|
}
|
2022-11-09 19:38:53 -05:00
|
|
|
|
2022-09-03 21:40:06 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
void precache_script_menu(int client_num, int config_string_index)
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
|
|
|
const char* menu = game::CL_GetConfigString(config_string_index);
|
|
|
|
if (menu)
|
|
|
|
{
|
|
|
|
if (!load_script_menu(client_num, menu))
|
|
|
|
{
|
|
|
|
game::Com_Error(game::ERR_DROP, "Could not load script menu file %s", menu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
utils::hook::detour cg_set_config_values_hook;
|
|
|
|
void cg_set_config_values_stub(int client_num)
|
|
|
|
{
|
|
|
|
cg_set_config_values_hook.invoke<void>(client_num);
|
|
|
|
|
|
|
|
auto nesting = game::R_PopRemoteScreenUpdate();
|
|
|
|
for (auto i = 3432; i < (3432 + 50); i++)
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
precache_script_menu(client_num, i);
|
2022-09-03 21:40:06 -04:00
|
|
|
}
|
2022-11-09 19:38:53 -05:00
|
|
|
|
2022-09-03 21:40:06 -04:00
|
|
|
game::R_PushRemoteScreenUpdate(nesting);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_mouse_event(int client_num, int x, int y)
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
const auto scr_place = game::ScrPlace_GetViewPlacement();
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
const auto v_x = x / (game::ScrPlace_HiResGetScaleX() * scr_place->scaleVirtualToFull[0]);
|
|
|
|
const auto v_y = y / (game::ScrPlace_HiResGetScaleY() * scr_place->scaleVirtualToFull[1]);
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
game::ui_info_array->cursor_x = v_x;
|
|
|
|
game::ui_info_array->cursor_x = v_y;
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
const auto cursor_visible = v_x >= 0.0 && v_x <= 640.0 && v_y >= 0.0 && v_y <= 480.0;
|
|
|
|
if (!cursor_visible)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto menu_count = *reinterpret_cast<int*>(0x352F9B8_b);
|
|
|
|
if (menu_count > 0)
|
|
|
|
{
|
|
|
|
game::ui_info_array->cursor_x = v_x;
|
|
|
|
game::ui_info_array->cursor_y = v_y;
|
|
|
|
game::ui_info_array->cursor_time = game::Sys_Milliseconds() + 200;
|
|
|
|
game::ui_info_array->ingame_cursor_visible = cursor_visible;
|
|
|
|
game::Display_MouseMove(game::ui_info_array);
|
2022-09-03 21:40:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ui_mouse_fix(int cx_, int cy_, int dx_, int dy_)
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
if ((*game::keyCatchers & 0x10) != 0 && !keys_bypass_menu())
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
tagPOINT cursor{};
|
2022-09-03 21:40:06 -04:00
|
|
|
|
2022-11-09 19:38:53 -05:00
|
|
|
game::CL_ShowSystemCursor(0);
|
|
|
|
game::CL_GetCursorPos(&cursor);
|
2022-09-03 21:40:06 -04:00
|
|
|
|
|
|
|
ui_mouse_event(0, cursor.x, cursor.y);
|
|
|
|
return 0;
|
|
|
|
}
|
2022-11-09 19:38:53 -05:00
|
|
|
|
2022-09-03 21:40:06 -04:00
|
|
|
return utils::hook::invoke<int>(0x1384C0_b, cx_, cy_, dx_, dy_);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool open_script_main_menu()
|
|
|
|
{
|
|
|
|
if (!script_main_menu.empty())
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
void* menu = game::Menus_FindByName(game::ui_info_array, script_main_menu.data());
|
2022-09-03 21:40:06 -04:00
|
|
|
if (menu)
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
game::Menus_Open(game::ui_info_array, menu, 0);
|
2022-09-03 21:40:06 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2022-11-09 19:38:53 -05:00
|
|
|
|
2022-09-03 21:40:06 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-09-12 12:24:19 -04:00
|
|
|
void lui_toggle_menu_stub(int controller_index, void* context)
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-09-12 12:24:19 -04:00
|
|
|
if (!game::VirtualLobby_Loaded())
|
2022-09-03 21:40:06 -04:00
|
|
|
{
|
2022-09-12 12:24:19 -04:00
|
|
|
if (!script_main_menu.empty())
|
|
|
|
{
|
|
|
|
if (game::Menu_IsMenuOpenAndVisible(0, script_main_menu.data()))
|
|
|
|
{
|
2022-11-09 19:38:53 -05:00
|
|
|
game::UI_SetActiveMenu(0, 0);
|
2022-09-12 12:24:19 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (open_script_main_menu())
|
|
|
|
{
|
|
|
|
*game::keyCatchers = *game::keyCatchers & 1 | 0x10;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2022-09-03 21:40:06 -04:00
|
|
|
}
|
2022-11-09 19:38:53 -05:00
|
|
|
|
|
|
|
// LUI_ToggleMenu
|
|
|
|
return utils::hook::invoke<void>(0x270A90_b, controller_index, context);
|
2022-09-03 21:40:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_script_main_menu(const std::string& menu)
|
|
|
|
{
|
|
|
|
script_main_menu = menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
class component final : public component_interface
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void post_unpack() override
|
|
|
|
{
|
|
|
|
if (!game::environment::is_mp())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// add back legacy menu precache
|
|
|
|
cg_set_config_values_hook.create(0x11AC50_b, cg_set_config_values_stub);
|
|
|
|
|
|
|
|
// add legacy menu mouse fix
|
|
|
|
utils::hook::call(0x5BA535_b, ui_mouse_fix);
|
|
|
|
|
2022-09-12 12:24:19 -04:00
|
|
|
// add script main menu
|
|
|
|
utils::hook::call(0x1E5143_b, lui_toggle_menu_stub); // (CL_ExecBinding)
|
|
|
|
utils::hook::call(0x131377_b, lui_toggle_menu_stub); // (UI_SetActiveMenu)
|
2022-09-03 21:40:06 -04:00
|
|
|
|
|
|
|
command::add("openmenu", [](const command::params& params)
|
|
|
|
{
|
|
|
|
if (params.size() != 2)
|
|
|
|
{
|
|
|
|
console::info("usage: openmenu <name>\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*game::keyCatchers = *game::keyCatchers & 1 | 0x10;
|
|
|
|
game::Menus_OpenByName(0, params.get(1));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
REGISTER_COMPONENT(menus::component)
|