diff --git a/src/client/component/images.cpp b/src/client/component/images.cpp index 531a3e44..e82c532c 100644 --- a/src/client/component/images.cpp +++ b/src/client/component/images.cpp @@ -34,7 +34,7 @@ namespace images return {}; } - return { std::move(data) }; + return {std::move(data)}; } std::optional load_raw_image_from_file(game::GfxImage* image) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 0a5843c9..613dedb0 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -13,15 +13,9 @@ #include "game/ui_scripting/lua/context.hpp" #include -#include namespace ui_scripting { - namespace - { - - } - class component final : public component_interface { public: @@ -49,27 +43,21 @@ namespace ui_scripting command::add("openluamenu", [](const command::params& params) { - printf("command openmenu\n"); const std::string name = params.get(1); scheduler::once([name]() { - printf("command openmenu scheduler\n"); ui_scripting::lua::open_menu(name); }, scheduler::pipeline::renderer); }); command::add("closeluamenu", [](const command::params& params) { - printf("command closemenu\n"); const std::string name = params.get(1); scheduler::once([name]() { - printf("command closemenu scheduler\n"); ui_scripting::lua::close_menu(name); }, scheduler::pipeline::renderer); }); - - utils::hook::nop(game::base_address + 0x5F22B1, 5); } }; } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 3c647ddb..ab366054 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -72,6 +72,22 @@ namespace game const char* name; }; + struct point + { + float x; + float y; + float f2; + float f3; + }; + + struct rectangle + { + point p0; + point p1; + point p2; + point p3; + }; + struct Glyph { unsigned short letter; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index a740d9a8..b0d0cd4f 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -83,6 +83,7 @@ namespace game float angle, float* color, Material* material)> R_AddCmdDrawStretchPicRotateXY{0x3C99B0}; WEAK symbol R_AddCmdDrawText{0x76C660}; + WEAK symbol R_DrawRectangle{0x76A280}; WEAK symbol R_AddCmdDrawTextWithCursor{0x76CAF0}; WEAK symbol R_RegisterFont{0x746FE0}; @@ -102,6 +103,7 @@ namespace game WEAK symbol Sys_IsDatabaseReady2{0x5A9FE0}; WEAK symbol UI_SafeTranslateString{0x5A2930}; + WEAK symbol UI_PlayLocalSoundAlias{0x606080}; WEAK symbol longjmp{0x89EED0}; WEAK symbol _setjmp{0x8EC2E0}; diff --git a/src/client/game/ui_scripting/element.cpp b/src/client/game/ui_scripting/element.cpp index 156b8fa0..9a917965 100644 --- a/src/client/game/ui_scripting/element.cpp +++ b/src/client/game/ui_scripting/element.cpp @@ -10,6 +10,23 @@ namespace ui_scripting namespace { uint64_t next_id; + float screen_max[2]; + + struct point + { + float x; + float y; + float f2; + float f3; + }; + + struct rectangle + { + point p0; + point p1; + point p2; + point p3; + }; std::unordered_map font_map = { @@ -43,6 +60,49 @@ namespace ui_scripting return 0.f; } } + + void draw_image(float x, float y, float w, float h, float* transform, float* color, game::Material* material) + { + game::rectangle rect; + + rect.p0.x = x; + rect.p0.y = y; + rect.p0.f2 = 0.f; + rect.p0.f3 = 1.f; + + rect.p1.x = x + w; + rect.p1.y = y; + rect.p1.f2 = 0.f; + rect.p1.f3 = 1.f; + + rect.p2.x = x + w; + rect.p2.y = y + h; + rect.p2.f2 = 0.f; + rect.p2.f3 = 1.f; + + rect.p3.x = x; + rect.p3.y = y + h; + rect.p3.f2 = 0.f; + rect.p3.f3 = 1.f; + + game::R_DrawRectangle(&rect, transform[0], transform[1], transform[2], transform[3], color, material); + } + + void check_resize() + { + screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0]; + screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1]; + } + + float relative(float value) + { + return (value / 1920.f) * screen_max[0]; + } + + int relative(int value) + { + return (int)(((float)value / 1920.f) * screen_max[0]); + } } element::element() @@ -163,6 +223,14 @@ namespace ui_scripting this->border_width[3] = left; } + void element::set_slice(float left_percent, float top_percent, float right_percent, float bottom_percent) + { + this->slice[0] = left_percent; + this->slice[1] = top_percent; + this->slice[2] = right_percent; + this->slice[3] = bottom_percent; + } + void element::set_material(const std::string& _material) { this->material = _material; @@ -178,69 +246,72 @@ namespace ui_scripting void element::render() const { + check_resize(); + const auto background_material = game::Material_RegisterHandle(this->material.data()); - game::R_AddCmdDrawStretchPic( - this->x + this->border_width[3], - this->y + this->border_width[0], - this->w, this->h, - 0.0f, 0.0f, 0.0f, 0.0f, + draw_image( + relative(this->x) + relative(this->border_width[3]), + relative(this->y) + relative(this->border_width[0]), + relative(this->w), + relative(this->h), + (float*)this->slice, (float*)this->background_color, background_material ); const auto _border_material = game::Material_RegisterHandle(this->border_material.data()); - game::R_AddCmdDrawStretchPic( - this->x, - this->y, - this->w + this->border_width[1] + this->border_width[3], - this->border_width[0], - 0.f, 0.f, 0.f, 0.f, - (float*)this->border_color, - _border_material - ); - - game::R_AddCmdDrawStretchPic( - this->x + this->border_width[3] + this->w, - this->y + this->border_width[0], - this->border_width[1], - this->h, - 0.f, 0.f, 0.f, 0.f, + draw_image( + relative(this->x), + relative(this->y), + relative(this->w) + relative(this->border_width[1]) + relative(this->border_width[3]), + relative(this->border_width[0]), + (float*)this->slice, (float*)this->border_color, _border_material ); - game::R_AddCmdDrawStretchPic( - this->x, - this->y + this->h + this->border_width[0], - this->w + this->border_width[1] + this->border_width[3], - this->border_width[2], - 0.f, 0.f, 0.f, 0.f, + draw_image( + relative(this->x) + relative(this->border_width[3]) + relative(this->w), + relative(this->y) + relative(this->border_width[0]), + relative(this->border_width[1]), + relative(this->h), + (float*)this->slice, (float*)this->border_color, _border_material ); - game::R_AddCmdDrawStretchPic( - this->x, - this->y + this->border_width[0], - this->border_width[3], - this->h, - 0.f, 0.f, 0.f, 0.f, + draw_image( + relative(this->x), + relative(this->y) + relative(this->h) + relative(this->border_width[0]), + relative(this->w) + relative(this->border_width[1]) + relative(this->border_width[3]), + relative(this->border_width[2]), + (float*)this->slice, + (float*)this->border_color, + _border_material + ); + + draw_image( + relative(this->x), + relative(this->y) + relative(this->border_width[0]), + relative(this->border_width[3]), + relative(this->h), + (float*)this->slice, (float*)this->border_color, _border_material ); if (!this->text.empty()) { - const auto _font = game::R_RegisterFont(this->font.data(), this->fontsize); + const auto _font = game::R_RegisterFont(this->font.data(), relative(this->fontsize)); const auto text_width = game::R_TextWidth(this->text.data(), 0x7FFFFFFF, _font); - auto _horzalign = get_align_value(this->horzalign, (float)text_width, this->w); - auto _vertalign = get_align_value(this->vertalign, (float)this->fontsize, this->h); + auto _horzalign = get_align_value(this->horzalign, (float)text_width, relative(this->w)); + auto _vertalign = get_align_value(this->vertalign, (float)relative(this->fontsize), relative(this->h)); game::R_AddCmdDrawText(this->text.data(), 0x7FFFFFFF, _font, - this->x + this->text_offset[0] + _horzalign + this->border_width[3], - this->y + this->text_offset[1] + _vertalign + this->fontsize + this->border_width[0], + relative(this->x) + relative(this->text_offset[0]) + _horzalign + relative(this->border_width[3]), + relative(this->y) + relative(this->text_offset[1]) + _vertalign + relative(this->fontsize) + relative(this->border_width[0]), 1.0f, 1.0f, 0.0f, (float*)this->color, 0 diff --git a/src/client/game/ui_scripting/element.hpp b/src/client/game/ui_scripting/element.hpp index 2d9bd110..f2402aa9 100644 --- a/src/client/game/ui_scripting/element.hpp +++ b/src/client/game/ui_scripting/element.hpp @@ -33,6 +33,8 @@ namespace ui_scripting void set_border_width(float top, float right, float bottom); void set_border_width(float top, float right, float bottom, float left); + void set_slice(float left_percent, float top_percent, float right_percent, float bottom_percent); + void set_rect(const float _x, const float _y, const float _w, const float _h); uint64_t id; @@ -51,6 +53,7 @@ namespace ui_scripting float background_color[4] = {0.f, 0.f, 0.f, 0.f}; float border_color[4] = {0.f, 0.f, 0.f, 0.f}; float border_width[4] = {0.f, 0.f, 0.f, 0.f}; + float slice[4] = {0.f, 0.f, 1.f, 1.f}; alignment horzalign = alignment::start; alignment vertalign = alignment::start; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 93d7cf5a..3004e908 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -17,6 +17,28 @@ namespace ui_scripting::lua std::unordered_map menus; std::vector elements; element ui_element; + float screen_max[2]; + + void check_resize() + { + screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0]; + screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1]; + } + + int relative_mouse(int value) + { + return (int)(((float)value / screen_max[0]) * 1920.f); + } + + int relative(int value) + { + return (int)(((float)value / 1920.f) * screen_max[0]); + } + + float relative(float value) + { + return (value / 1920.f) * screen_max[0]; + } scripting::script_value convert(const sol::lua_value& value) { @@ -64,6 +86,8 @@ namespace ui_scripting::lua void render_menus() { + check_resize(); + for (const auto& menu : menus) { if (menu.second.visible) @@ -483,6 +507,7 @@ namespace ui_scripting::lua static_cast(&element::set_border_width) ); element_type["settextoffset"] = &element::set_text_offset; + element_type["setslice"] = &element::set_slice; element_type["onnotify"] = [&handler](element& element, const std::string& event, const event_callback& callback) @@ -704,6 +729,22 @@ namespace ui_scripting::lua ::game::R_AddCmdDrawStretchPic(x, y, width, height, s0, t0, s1, t1, _color, _material); }; + game_type["playsound"] = [](const game&, const std::string& sound) + { + ::game::UI_PlayLocalSoundAlias(0, sound.data()); + }; + + game_type["getwindowsize"] = [](const game&, const sol::this_state s) + { + const auto size = ::game::ScrPlace_GetViewPlacement()->realViewportSize; + + auto screen = sol::table::create(s.lua_state()); + screen["x"] = size[0]; + screen["y"] = size[1]; + + return screen; + }; + struct player { }; @@ -787,8 +828,6 @@ namespace ui_scripting::lua void open_menu(const std::string& name) { - printf("open_menu\n"); - if (menus.find(name) == menus.end()) { return; @@ -799,8 +838,6 @@ namespace ui_scripting::lua void close_menu(const std::string& name) { - printf("close_menu\n"); - if (menus.find(name) == menus.end()) { return; @@ -874,7 +911,8 @@ namespace ui_scripting::lua if (type == "mousemove") { - handle_mousemove_event(this->state_, this->event_handler_, arguments[0], arguments[1]); + handle_mousemove_event(this->state_, this->event_handler_, + relative_mouse(arguments[0]), relative_mouse(arguments[1])); } } diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 0e0ff93a..6ce9656a 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -24,8 +24,6 @@ namespace ui_scripting::lua::engine return; } - printf("here\n"); - const auto scripts = utils::io::list_files(script_dir); for (const auto& script : scripts)