diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 355345a6..3d44b5aa 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -32,7 +32,7 @@ namespace branding public: void post_unpack() override { - localized_strings::override("MENU_SP_CAMPAIGN", "H2-Mod"); + localized_strings::override("MENU_SP_CAMPAIGN", "H2-MOD"); } }; } diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 175a5431..fa8f941c 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -49,7 +49,6 @@ namespace input void cl_mouse_move_stub(const int local_client_num, int x, int y) { ui_scripting::lua::engine::ui_event("mousemove", {x, y}); - cl_mouse_move_hook.invoke(local_client_num, x, y); } } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 501a00a4..6cc4f349 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -89,6 +89,14 @@ namespace game point p3; }; + struct rgba + { + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; + }; + struct Glyph { unsigned short letter; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 47a64cb7..61619ba6 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -87,11 +87,15 @@ namespace game float* color, Material* material)> R_AddCmdDrawStretchPic{0x3C9710}; WEAK symbol R_AddCmdDrawStretchPicRotateXY{0x3C99B0}; - WEAK symbol R_AddCmdDrawText{0x76C660}; + WEAK symbol R_AddCmdDrawText2{0x76C860}; WEAK symbol R_DrawRectangle{0x76A280}; WEAK symbol R_AddCmdDrawTextWithCursor{0x76CAF0}; + WEAK symbol R_AddCmdDrawTextGradient{0x76C570}; WEAK symbol R_RegisterFont{0x746FE0}; WEAK symbol R_TextWidth{0x7472A0}; WEAK symbol R_SyncRenderThread{0x76E7D0}; diff --git a/src/client/game/ui_scripting/element.cpp b/src/client/game/ui_scripting/element.cpp index 1ca2e5e9..0efb7fa9 100644 --- a/src/client/game/ui_scripting/element.cpp +++ b/src/client/game/ui_scripting/element.cpp @@ -104,6 +104,27 @@ namespace ui_scripting { return (int)ceil(((float)value / 1920.f) * screen_max[0]); } + + game::rgba float_to_rgba(const float* color) + { + game::rgba rgba; + rgba.r = (uint8_t)(color[0] * 255.f); + rgba.g = (uint8_t)(color[1] * 255.f); + rgba.b = (uint8_t)(color[2] * 255.f); + rgba.a = (uint8_t)(color[3] * 255.f); + return rgba; + } + + void draw_text(const char* text, game::Font_s* font, float x, float y, float x_scale, float y_scale, float rotation, + int style, float* color, float* second_color, float* glow_color) + { + const auto result = (uint64_t)game::R_AddCmdDrawText(text, 0x7FFFFFFF, font, x, y, x_scale, y_scale, rotation, color, style); + *reinterpret_cast(result + 188) = glow_color[0]; + *reinterpret_cast(result + 192) = glow_color[1]; + *reinterpret_cast(result + 196) = glow_color[2]; + *reinterpret_cast(result + 200) = glow_color[3]; + *reinterpret_cast(result + 228) = float_to_rgba(second_color); + } } element::element() @@ -177,6 +198,22 @@ namespace ui_scripting this->text_offset[1] = _y; } + void element::set_scale(float _x, float _y) + { + this->x_scale = _x; + this->y_scale = _y; + } + + void element::set_rotation(float _rotation) + { + this->rotation = _rotation; + } + + void element::set_style(int _style) + { + this->style = _style; + } + void element::set_background_color(float r, float g, float b, float a) { this->background_color[0] = r; @@ -193,6 +230,15 @@ namespace ui_scripting this->color[3] = a; } + void element::set_second_color(float r, float g, float b, float a) + { + this->use_gradient = true; + this->second_color[0] = r; + this->second_color[1] = g; + this->second_color[2] = b; + this->second_color[3] = a; + } + void element::set_glow_color(float r, float g, float b, float a) { this->glow_color[0] = r; @@ -340,16 +386,22 @@ namespace ui_scripting 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::CL_DrawTextPhysicalWithEffects( + float transparent[4] = {0.f, 0.f, 0.f, 0.f}; + + const auto _x = relative(this->x) + relative(this->text_offset[0]) + _horzalign + relative(this->border_width[3]); + const auto _y = relative(this->y) + relative(this->text_offset[1]) + _vertalign + relative(this->fontsize) + relative(this->border_width[0]); + + draw_text( this->text.data(), - 0x7FFFFFFF, _font, - 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.f, 1.f, - (float*)this->color, 0, - (float*)this->glow_color, - 0, 0, 0, 0, 0, 0, 0 + _x, _y, + this->x_scale, + this->y_scale, + this->rotation, + this->style, + (float*)this->color, + (float*)(this->use_gradient ? this->second_color : this->color), + (float*)this->glow_color ); } } diff --git a/src/client/game/ui_scripting/element.hpp b/src/client/game/ui_scripting/element.hpp index 5ca955df..ac3855fc 100644 --- a/src/client/game/ui_scripting/element.hpp +++ b/src/client/game/ui_scripting/element.hpp @@ -22,9 +22,14 @@ namespace ui_scripting void set_font(const std::string& _font); void set_font(const std::string& _font, const int _fontsize); void set_color(float r, float g, float b, float a); + void set_second_color(float r, float g, float b, float a); void set_glow_color(float r, float g, float b, float a); void set_text_offset(float x, float y); + void set_scale(float x, float y); + void set_rotation(float rotation); + void set_style(int style); + void set_background_color(float r, float g, float b, float a); void set_material(const std::string& material); @@ -44,16 +49,23 @@ namespace ui_scripting void render() const; bool hidden = false; + bool use_gradient = false; float x = 0.f; float y = 0.f; float w = 0.f; float h = 0.f; + float rotation = 0; + float x_scale = 1.f; + float y_scale = 1.f; + + int style = 0; int fontsize = 20; float text_offset[2] = {0.f, 0.f}; float color[4] = {1.f, 1.f, 1.f, 1.f}; + float second_color[4] = {1.f, 1.f, 1.f, 1.f}; float glow_color[4] = {0.f, 0.f, 0.f, 0.f}; float background_color[4] = {0.f, 0.f, 0.f, 0.f}; float border_color[4] = {0.f, 0.f, 0.f, 0.f}; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 1840135c..4fb743fb 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -207,6 +207,7 @@ namespace ui_scripting::lua element_type["settext"] = &element::set_text; element_type["setmaterial"] = &element::set_material; element_type["setcolor"] = &element::set_color; + element_type["setsecondcolor"] = &element::set_second_color; element_type["setglowcolor"] = &element::set_glow_color; element_type["setbackcolor"] = &element::set_background_color; element_type["setbordercolor"] = &element::set_border_color; @@ -217,6 +218,9 @@ namespace ui_scripting::lua static_cast(&element::set_border_width) ); element_type["settextoffset"] = &element::set_text_offset; + element_type["setscale"] = &element::set_scale; + element_type["setrotation"] = &element::set_rotation; + element_type["setyle"] = &element::set_style; element_type["setslice"] = &element::set_slice; element_type["getrect"] = [](const sol::this_state s, element& element) @@ -274,6 +278,50 @@ namespace ui_scripting::lua } ); + element_type["scalex"] = sol::property( + [](element& element) + { + return element.x_scale; + }, + [](element& element, float x_scale) + { + element.x_scale = x_scale; + } + ); + + element_type["scaley"] = sol::property( + [](element& element) + { + return element.y_scale; + }, + [](element& element, float y_scale) + { + element.y_scale = y_scale; + } + ); + + element_type["rotation"] = sol::property( + [](element& element) + { + return element.rotation; + }, + [](element& element, float rotation) + { + element.rotation = rotation; + } + ); + + element_type["style"] = sol::property( + [](element& element) + { + return element.style; + }, + [](element& element, int style) + { + element.style = style; + } + ); + element_type["color"] = sol::property( [](element& element, const sol::this_state s) { @@ -293,6 +341,37 @@ namespace ui_scripting::lua } ); + element_type["secondcolor"] = sol::property( + [](element& element, const sol::this_state s) + { + auto color = sol::table::create(s.lua_state()); + color["r"] = element.second_color[0]; + color["g"] = element.second_color[1]; + color["b"] = element.second_color[2]; + color["a"] = element.second_color[3]; + return color; + }, + [](element& element, const sol::lua_table color) + { + element.use_gradient = true; + element.second_color[0] = color["r"].get_type() == sol::type::number ? color["r"].get() : 0.f; + element.second_color[1] = color["g"].get_type() == sol::type::number ? color["g"].get() : 0.f; + element.second_color[2] = color["b"].get_type() == sol::type::number ? color["b"].get() : 0.f; + element.second_color[3] = color["a"].get_type() == sol::type::number ? color["a"].get() : 0.f; + } + ); + + element_type["usegradient"] = sol::property( + [](element& element, const sol::this_state s) + { + return element.use_gradient; + }, + [](element& element, bool use_gradient) + { + element.use_gradient = use_gradient; + } + ); + element_type["glowcolor"] = sol::property( [](element& element, const sol::this_state s) { @@ -695,7 +774,10 @@ namespace ui_scripting::lua game_type["luiopen"] = [](const game&, const std::string& menu) { - ::game::LUI_OpenMenu(0, menu.data(), 0, 0, 0); + ::scheduler::once([menu]() + { + ::game::LUI_OpenMenu(0, menu.data(), 0, 0, 0); + }, ::scheduler::pipeline::renderer); }; game_type["newmenuoverlay"] = [](const game&, const std::string& name, const std::string& menu_name) diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 4863c1c0..10339924 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -418,23 +418,20 @@ namespace ui_scripting::lua::engine void ui_event(const std::string& type, const std::vector& arguments) { - ::scheduler::once([type, arguments]() + if (type == "key") { - if (type == "key") - { - handle_key_event(arguments[0], arguments[1]); - } + handle_key_event(arguments[0], arguments[1]); + } - if (type == "char") - { - handle_char_event(arguments[0]); - } + if (type == "char") + { + handle_char_event(arguments[0]); + } - if (type == "mousemove") - { - handle_mousemove_event(relative_mouse(arguments[0]), relative_mouse(arguments[1])); - } - }, ::scheduler::pipeline::renderer); + if (type == "mousemove") + { + handle_mousemove_event(relative_mouse(arguments[0]), relative_mouse(arguments[1])); + } } void notify(const event& e)