From 371aaaa9f5d8bb01c734c2e62499eecd82781ad4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 12 Nov 2025 12:29:07 +0300 Subject: [PATCH 1/3] make exchange slot available as 'hud.exchange-slot' --- src/frontend/hud.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 89789e29..5cc16119 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -469,6 +469,7 @@ void Hud::showExchangeSlot() { gui, SlotLayout(-1, glm::vec2(), false, false, nullptr, nullptr, nullptr) ); + exchangeSlot->setId("hud.exchange-slot"); exchangeSlot->bind(exchangeSlotInv->getId(), exchangeSlotInv->getSlot(0), &content); exchangeSlot->setColor(glm::vec4()); exchangeSlot->setInteractive(false); From b5e69f1eae6f7493ec192de506ea5ecd7a4d7ce6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 12 Nov 2025 18:43:34 +0300 Subject: [PATCH 2/3] make ui_element.id access non-throwing --- src/logic/scripting/lua/libs/libgui.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 3697d39c..a051aa56 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -30,14 +30,17 @@ using namespace gui; using namespace scripting; static DocumentNode get_document_node_impl( - lua::State*, const std::string& name, const std::string& nodeName + lua::State*, const std::string& name, const std::string& nodeName, bool throwable=true ) { auto doc = engine->getAssets()->get(name); if (doc == nullptr) { - throw std::runtime_error("document '" + name + "' not found"); + if (throwable) { + throw std::runtime_error("document '" + name + "' not found"); + } + return {nullptr, nullptr}; } auto node = doc->get(nodeName); - if (node == nullptr) { + if (node == nullptr && throwable) { throw std::runtime_error( "document '" + name + "' has no element with id '" + nodeName + "'" ); @@ -459,6 +462,9 @@ static int p_get_content_offset(UINode* node, lua::State* L) { return lua::pushvec(L, node->getContentOffset()); } static int p_get_id(UINode* node, lua::State* L) { + if (node == nullptr) { + return 0; + } return lua::pushstring(L, node->getId()); } static int p_get_color(UINode* node, lua::State* L) { @@ -540,6 +546,10 @@ static int p_get_options(UINode* node, lua::State* L) { return 0; } +static bool is_node_required(std::string_view attr) { + return attr != "id"; +} + static int l_gui_getattr(lua::State* L) { if (!lua::isstring(L, 1)) { throw std::runtime_error("document name is not a string"); @@ -568,6 +578,7 @@ static int l_gui_getattr(lua::State* L) { throw std::runtime_error("attribute name is not a string"); } auto attr = lua::require_string(L, 3); + bool required = is_node_required(attr); static const std::unordered_map< std::string_view, @@ -630,7 +641,7 @@ static int l_gui_getattr(lua::State* L) { }; auto func = getters.find(attr); if (func != getters.end()) { - auto docnode = get_document_node_impl(L, docname, element); + auto docnode = get_document_node_impl(L, docname, element, required); auto node = docnode.node; return func->second(node.get(), L); } From ef656e9ff1a0a5074aabf0470005aa5a2227bf39 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 12 Nov 2025 18:49:04 +0300 Subject: [PATCH 3/3] revert non-throwing 'id' and add 'exists' property & update doc/*/scripting/ui.md --- doc/en/scripting/ui.md | 1 + doc/ru/scripting/ui.md | 1 + src/logic/scripting/lua/libs/libgui.cpp | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md index 80750501..c35bf908 100644 --- a/doc/en/scripting/ui.md +++ b/doc/en/scripting/ui.md @@ -37,6 +37,7 @@ Properties that apply to all elements: | Name | Type | Read | Write | Description | | ------------- | ------- | ---- | ----- | ------------------------------------------- | | id | string | yes | *no* | element id | +| exists | bool | yes | *no* | checks if element exists | | pos | vec2 | yes | yes | element position inside a container | | wpos | vec2 | yes | yes | element position inside the window | | size | vec2 | yes | yes | element size | diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md index c6c769ac..a6d6006d 100644 --- a/doc/ru/scripting/ui.md +++ b/doc/ru/scripting/ui.md @@ -37,6 +37,7 @@ document["worlds-panel"]:clear() | Название | Тип | Чтение | Запись | Описание | | ------------- | ------- | ------ | ------ | ----------------------------------------- | | id | string | да | *нет* | идентификатор элемента | +| exists | bool | да | *нет* | проверяет, существует ли элемент | | pos | vec2 | да | да | позиция элемента внутри контейнера | | wpos | vec2 | да | да | позиция элемента в окне | | size | vec2 | да | да | размер элемента | diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index a051aa56..cdf65898 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -546,8 +546,12 @@ static int p_get_options(UINode* node, lua::State* L) { return 0; } +static int p_is_exists(UINode* node, lua::State* L) { + return lua::pushboolean(L, node != nullptr); +} + static bool is_node_required(std::string_view attr) { - return attr != "id"; + return attr != "exists"; } static int l_gui_getattr(lua::State* L) { @@ -585,6 +589,7 @@ static int l_gui_getattr(lua::State* L) { std::function> getters { {"id", p_get_id}, + {"exists", p_is_exists}, {"color", p_get_color}, {"hoverColor", p_get_hover_color}, {"pressedColor", p_get_pressed_color},