From 56c4d68c845a0bd0e35c1d04a9ad80b12e293b9a Mon Sep 17 00:00:00 2001 From: neveix Date: Thu, 13 Aug 2026 20:56:59 +0500 Subject: [PATCH 1/8] add item dropping outside of inventory --- res/content/base/scripts/hud.lua | 58 ++++++++++++++++------ src/graphics/ui/GUI.cpp | 40 +++++++++++++-- src/graphics/ui/GUI.hpp | 2 +- src/graphics/ui/elements/InventoryView.cpp | 30 +++++++++++ src/graphics/ui/elements/InventoryView.hpp | 2 + src/graphics/ui/elements/UINode.hpp | 3 ++ src/logic/scripting/scripting.hpp | 1 + src/logic/scripting/scripting_hud.cpp | 17 +++++++ 8 files changed, 132 insertions(+), 21 deletions(-) diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 0ec427c11..3620566e5 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -3,29 +3,55 @@ local base_util = require "util" local DROP_FORCE = 8 local DROP_INIT_VEL = {0, 3, 0} +---@param mode integer 0 - whole stack, 1 - single item, 2 - dupe whole stack +function drop_from_slot(invid, slot, mode) + local pid = hud.get_player() + if mode == 2 and !player.is_infinite_items(pid) then + return + end + local itemid, itemcount = inventory.get(invid, slot) + if itemid == 0 then + return + end + + local drop_itemcount = 1 + if mode == 0 then + drop_itemcount = itemcount + end + if mode == 2 then + drop_itemcount = item.stack_size(itemid) + else + inventory.set(invid, slot, itemid, itemcount - drop_itemcount) + end + + local data = inventory.get_all_data(invid, slot) + local pvel = { player.get_vel(pid) } + local ppos = vec3.add({ player.get_pos(pid) }, { 0, 0.7, 0 }) + local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) + local drop = base_util.drop(ppos, itemid, drop_itemcount, data, 1.5) + if not drop then + return + end + local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) + drop.rigidbody:set_vel(velocity) +end + +function on_inventory_clicked_outside(exc_invid, exc_slot, mode) + drop_from_slot(exc_invid, exc_slot, mode) +end + function on_hud_open() - input.add_callback("player.drop", function () + input.add_callback("player.drop", function() if hud.is_paused() or hud.is_inventory_open() then return end local pid = hud.get_player() local invid, slot = player.get_inventory(pid) - local itemid, itemcount = inventory.get(invid, slot) - if itemid == 0 then - return + local mode = 1 + if input.is_pressed("key:left-ctrl") or input.is_pressed("key:right-ctrl") then + mode = 0 end - local data = inventory.get_all_data(invid, slot) - inventory.set(invid, slot, itemid, itemcount-1) - - local pvel = {player.get_vel(pid)} - local ppos = vec3.add({player.get_pos(pid)}, {0, 0.7, 0}) - local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - local drop = base_util.drop(ppos, itemid, 1, data, 1.5) - if not drop then - return - end - local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) - drop.rigidbody:set_vel(velocity) + drop_from_slot(invid, slot, mode) end) rules.create("do-loot-non-player", true) end diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index 8bfe3a341..fb4320113 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -14,7 +14,6 @@ #include "frontend/UiDocument.hpp" #include "frontend/locale.hpp" #include "graphics/core/Batch2D.hpp" -#include "graphics/core/LineBatch.hpp" #include "graphics/core/Shader.hpp" #include "graphics/core/Font.hpp" #include "graphics/core/DrawContext.hpp" @@ -179,6 +178,8 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { } it = mouseOver.erase(it); } + + bool focusHappened = false; if (input.jclicked(Mousecode::BUTTON_1)) { if (pressed == nullptr && this->hover) { @@ -196,10 +197,10 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { if (focus != pressed) { focus = pressed; focus->onFocus(); - return; + focusHappened = true; } } - if (this->hover == nullptr && focus) { + if (this->hover == nullptr && focus && !focusHappened) { focus->defocus(); focus = nullptr; } @@ -208,13 +209,44 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { pressed = nullptr; } - if (hover) { + if (hover && !focusHappened) { for (Mousecode code : MOUSECODES_ALL) { if (input.jclicked(code)) { hover->clicked(code); } } } + performClickOutside(frame, delta, cursorPos); +} + +void GUI::performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos) { + auto nodes = frame.getNodes(); + std::vector> activeNodes; + + for (const auto& node : nodes) { + if (node && node->isVisible() && node->isInteractive()) { + activeNodes.push_back(node); + } + } + + for (Mousecode code : {Mousecode::BUTTON_1, Mousecode::BUTTON_2, Mousecode::BUTTON_3}) { + if (input.jclicked(code)) { + bool isOverAnyNode = false; + for (const auto& node : activeNodes) { + if (node && node->isInside(cursorPos)) { + isOverAnyNode = true; + break; + } + } + if (!isOverAnyNode) { + for (const auto& node : activeNodes) { + if (node) { + node->clickedOutside(code); + } + } + } + } + } } void GUI::actFocused() { diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index 97fc0ed37..9b65089c1 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -2,7 +2,6 @@ #include "delegates.hpp" -#include #include #include #include @@ -93,6 +92,7 @@ namespace gui { bool debug = false; void actMouse(Frame& frame, float delta, const CursorState& cursor); + void performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos); void actFocused(); void updateTooltip(float delta); void resetTooltip(); diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 144d80397..09b131cba 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -1,5 +1,7 @@ #include "InventoryView.hpp" +#include + #include #include @@ -19,6 +21,7 @@ #include "items/Inventories.hpp" #include "items/Inventory.hpp" #include "items/ItemDef.hpp" +#include "items/ItemStack.hpp" #include "logic/scripting/scripting.hpp" #include "maths/voxmaths.hpp" #include "objects/Player.hpp" @@ -610,6 +613,33 @@ void InventoryView::setPos(const glm::vec2& pos) { Container::setPos(pos - origin); } +void InventoryView::clickedOutside(Mousecode button) { + // root is the id of the main inventory + if (getId() != "root") { + return; + } + int mode; + if (button == Mousecode::BUTTON_1) { + mode = 0; + } else if (button == Mousecode::BUTTON_2) { + mode = 1; + } else if (button == Mousecode::BUTTON_3) { + mode = 2; + } else { + return; + }; + auto exchangeSlot = std::dynamic_pointer_cast( + gui.get(SlotView::EXCHANGE_SLOT_NAME)); + if (exchangeSlot == nullptr) { + return; + } + ItemStack& grabbed = exchangeSlot->getStack(); + if (grabbed.isEmpty()) { + return; + } + scripting::on_inventory_clicked_outside(exchangeSlot->getInventoryId(), 0, mode); +} + void InventoryView::setOrigin(const glm::vec2& origin) { this->origin = origin; } diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index 243d8b6b5..a0d3c76e9 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -143,6 +143,8 @@ namespace gui { void setSelected(int index); + void clickedOutside(Mousecode button) override; + void bind( const std::shared_ptr& inventory, const Content* content diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index fb699a737..bd2254567 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -207,6 +207,9 @@ namespace gui { virtual void onFocus(); virtual void doubleClick(int x, int y); virtual void click(int x, int y); + virtual void clickedOutside(Mousecode button) { + // Empty for all UINodes, except InventoryView + } virtual void clicked(Mousecode button); virtual void mouseMove(int x, int y) {}; virtual void mouseRelease(int x, int y); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 0044213cd..a4f6adc83 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -109,6 +109,7 @@ namespace scripting { void on_inventory_open(const Player* player, const Inventory& inventory); void on_inventory_closed(const Player* player, const Inventory& inventory); void on_inventory_interact(int invid, int slot, int action, int mode); + void on_inventory_clicked_outside(int exchange_invid, int exchange_slot, int mode); void on_player_tick(Player* player, int tps); diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index 59b928d21..92ba4e4ca 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -110,6 +110,22 @@ void scripting::on_inventory_interact(int invid, int slot, int action, int mode) } } +void scripting::on_inventory_clicked_outside(int exchange_invid, int exchange_slot, int mode) { + auto L = lua::get_main_state(); + for (auto& pack : content_control->getAllContentPacks()) { + lua::emit_event( + L, + pack.id + ":.inventoryclickedoutside", + [&](lua::State* L) { + lua::pushinteger(L, exchange_invid); + lua::pushinteger(L, exchange_slot); + lua::pushinteger(L, mode); + return 3; + } + ); + } +} + void scripting::load_hud_script( const scriptenv& senv, const std::string& packid, @@ -127,6 +143,7 @@ void scripting::load_hud_script( register_event(env, "on_hud_render", packid + ":.hudrender"); register_event(env, "on_hud_close", packid + ":.hudclose"); register_event(env, "on_inventory_interact", packid + ":.inventoryinteract"); + register_event(env, "on_inventory_clicked_outside", packid + ":.inventoryclickedoutside"); } gui::PageLoaderFunc scripting::create_page_loader() { From 2a4b8b029728ab9ca41ece5592c307f889868eea Mon Sep 17 00:00:00 2001 From: neveix Date: Thu, 13 Aug 2026 21:02:53 +0500 Subject: [PATCH 2/8] delete redundant imports --- src/graphics/ui/elements/InventoryView.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 09b131cba..e99a86d33 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -1,7 +1,5 @@ #include "InventoryView.hpp" -#include - #include #include @@ -14,11 +12,8 @@ #include "graphics/core/Batch2D.hpp" #include "graphics/core/DrawContext.hpp" #include "graphics/core/Font.hpp" -#include "graphics/core/Shader.hpp" -#include "graphics/core/Texture.hpp" #include "graphics/render/BlocksPreview.hpp" #include "graphics/ui/GUI.hpp" -#include "items/Inventories.hpp" #include "items/Inventory.hpp" #include "items/ItemDef.hpp" #include "items/ItemStack.hpp" From 7c97966377cba033b0369973d06249f0375f8cc3 Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 00:43:40 +0500 Subject: [PATCH 3/8] switch to inventory drop area --- res/content/base/modules/util.lua | 39 +++++++++++++++++++++ res/content/base/scripts/hud.lua | 46 +++---------------------- src/frontend/hud.cpp | 17 +++++++++ src/frontend/hud.hpp | 4 +++ src/logic/scripting/lua/libs/libhud.cpp | 10 ++++++ 5 files changed, 75 insertions(+), 41 deletions(-) diff --git a/res/content/base/modules/util.lua b/res/content/base/modules/util.lua index 874e6d3d6..dbad0c2a1 100644 --- a/res/content/base/modules/util.lua +++ b/res/content/base/modules/util.lua @@ -1,5 +1,44 @@ local util = {} +local DROP_FORCE = 8 +local DROP_INIT_VEL = {0, 3, 0} + +---@param mode integer 0 - whole stack, 1 - single item, 2 - dupe whole stack +function util.drop_from_slot(invid, slot, mode) + if invid == 0 then + return + end + local pid = hud.get_player() + if mode == 2 and !player.is_infinite_items(pid) then + return + end + local itemid, itemcount = inventory.get(invid, slot) + if itemid == 0 then + return + end + + local drop_itemcount = 1 + if mode == 0 then + drop_itemcount = itemcount + end + if mode == 2 then + drop_itemcount = item.stack_size(itemid) + else + inventory.set(invid, slot, itemid, itemcount - drop_itemcount) + end + + local data = inventory.get_all_data(invid, slot) + local pvel = { player.get_vel(pid) } + local ppos = vec3.add({ player.get_pos(pid) }, { 0, 0.7, 0 }) + local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) + local drop = util.drop(ppos, itemid, drop_itemcount, data, 1.5) + if not drop then + return + end + local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) + drop.rigidbody:set_vel(velocity) +end + function util.drop(ppos, itemid, count, data, pickup_delay) if itemid == 0 or not itemid then return nil diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 3620566e5..d0e3d1532 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -1,46 +1,10 @@ local base_util = require "util" -local DROP_FORCE = 8 -local DROP_INIT_VEL = {0, 3, 0} - ----@param mode integer 0 - whole stack, 1 - single item, 2 - dupe whole stack -function drop_from_slot(invid, slot, mode) - local pid = hud.get_player() - if mode == 2 and !player.is_infinite_items(pid) then - return - end - local itemid, itemcount = inventory.get(invid, slot) - if itemid == 0 then - return - end - - local drop_itemcount = 1 - if mode == 0 then - drop_itemcount = itemcount - end - if mode == 2 then - drop_itemcount = item.stack_size(itemid) - else - inventory.set(invid, slot, itemid, itemcount - drop_itemcount) - end - - local data = inventory.get_all_data(invid, slot) - local pvel = { player.get_vel(pid) } - local ppos = vec3.add({ player.get_pos(pid) }, { 0, 0.7, 0 }) - local throw_force = vec3.mul(player.get_dir(pid), DROP_FORCE) - local drop = base_util.drop(ppos, itemid, drop_itemcount, data, 1.5) - if not drop then - return - end - local velocity = vec3.add(throw_force, vec3.add(pvel, DROP_INIT_VEL)) - drop.rigidbody:set_vel(velocity) -end - -function on_inventory_clicked_outside(exc_invid, exc_slot, mode) - drop_from_slot(exc_invid, exc_slot, mode) -end - function on_hud_open() + events.on("core:drop_outside_inventory", function(mode) + local invid = hud.get_exchange_inventory() + base_util.drop_from_slot(invid, 0, mode) + end) input.add_callback("player.drop", function() if hud.is_paused() or hud.is_inventory_open() then return @@ -51,7 +15,7 @@ function on_hud_open() if input.is_pressed("key:left-ctrl") or input.is_pressed("key:right-ctrl") then mode = 0 end - drop_from_slot(invid, slot, mode) + base_util.drop_from_slot(invid, slot, mode) end) rules.create("do-loot-non-player", true) end diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 1aa03436b..d89571089 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -1,3 +1,5 @@ +#include + #include "hud.hpp" #include "ContentGfxCache.hpp" @@ -174,6 +176,14 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player) gui, "" ); + + inventoryDropArea = guiutil::create( + gui, + R"()" + ); uicamera = std::make_unique(glm::vec3(), 1); uicamera->perspective = false; @@ -188,6 +198,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player) gui.add(debugPanel); gui.add(darkOverlay); + gui.add(inventoryDropArea); gui.add(hotbarView); gui.add(contentAccessPanel); @@ -213,6 +224,7 @@ Hud::~Hud() { } gui.remove(hotbarView); gui.remove(darkOverlay); + gui.remove(inventoryDropArea); gui.remove(contentAccessPanel); gui.remove(debugPanel); } @@ -358,6 +370,7 @@ void Hud::update(bool visible) { contentAccess->setMinSize(glm::vec2(1, windowSize.y)); hotbarView->setVisible(visible && !(secondUI && !inventoryView)); darkOverlay->setVisible(isMenuOpen); + inventoryDropArea->setVisible(inventoryOpen); menu.setVisible(isMenuOpen); if (visible) { @@ -739,6 +752,10 @@ std::shared_ptr Hud::getSecondInventory() { return nullptr; } +std::shared_ptr Hud::getExchangeInventory() { + return exchangeSlotInv; +} + bool Hud::isContentAccess() const { return showContentPanel; } diff --git a/src/frontend/hud.hpp b/src/frontend/hud.hpp index f80c36369..f40a53581 100644 --- a/src/frontend/hud.hpp +++ b/src/frontend/hud.hpp @@ -93,6 +93,8 @@ class Hud : public util::ObjectsKeeper { std::shared_ptr debugPanel; /// @brief Overlay used in pause mode std::shared_ptr darkOverlay; + /// @brief Overlay used in inventory + std::shared_ptr inventoryDropArea; /// @brief Inventories interaction agent (grabbed item) std::shared_ptr exchangeSlot; /// @brief Exchange slot inventory (1 slot only) @@ -207,6 +209,8 @@ public: std::shared_ptr getSecondInventory(); + std::shared_ptr getExchangeInventory(); + bool isContentAccess() const; void setContentAccess(bool flag); diff --git a/src/logic/scripting/lua/libs/libhud.cpp b/src/logic/scripting/lua/libs/libhud.cpp index 7f5c893c5..a457ca6ee 100644 --- a/src/logic/scripting/lua/libs/libhud.cpp +++ b/src/logic/scripting/lua/libs/libhud.cpp @@ -149,6 +149,15 @@ static int l_get_second_inventory(lua::State* L) { } } +static int l_get_exchange_inventory(lua::State* L) { + auto inventory = hud->getExchangeInventory(); + if (inventory == nullptr) { + return lua::pushinteger(L, 0); + } else { + return lua::pushinteger(L, inventory->getId()); + } +} + static int l_get_player(lua::State* L) { auto player = hud->getPlayer(); return lua::pushinteger(L, player->getId()); @@ -216,6 +225,7 @@ const luaL_Reg hudlib[] = { {"show_overlay", wrap_hud}, {"get_block_inventory", wrap_hud}, {"get_second_inventory", wrap_hud}, + {"get_exchange_inventory", wrap_hud}, {"close", wrap_hud}, {"pause", wrap_hud}, {"resume", wrap_hud}, From c2f7f33bbf7c190d90547a8c5cb41778c6f335ae Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 00:59:55 +0500 Subject: [PATCH 4/8] revert creation of clickOutside --- src/frontend/hud.cpp | 6 ++-- src/graphics/ui/GUI.cpp | 39 ++-------------------- src/graphics/ui/GUI.hpp | 2 +- src/graphics/ui/elements/InventoryView.cpp | 28 ---------------- src/graphics/ui/elements/InventoryView.hpp | 2 -- src/graphics/ui/elements/UINode.hpp | 3 -- 6 files changed, 6 insertions(+), 74 deletions(-) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index d89571089..3a4557797 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -1,5 +1,3 @@ -#include - #include "hud.hpp" #include "ContentGfxCache.hpp" @@ -180,8 +178,8 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player) inventoryDropArea = guiutil::create( gui, R"()" ); diff --git a/src/graphics/ui/GUI.cpp b/src/graphics/ui/GUI.cpp index fb4320113..944c32fb5 100644 --- a/src/graphics/ui/GUI.cpp +++ b/src/graphics/ui/GUI.cpp @@ -178,8 +178,6 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { } it = mouseOver.erase(it); } - - bool focusHappened = false; if (input.jclicked(Mousecode::BUTTON_1)) { if (pressed == nullptr && this->hover) { @@ -197,10 +195,10 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { if (focus != pressed) { focus = pressed; focus->onFocus(); - focusHappened = true; + return; } } - if (this->hover == nullptr && focus && !focusHappened) { + if (this->hover == nullptr && focus) { focus->defocus(); focus = nullptr; } @@ -209,44 +207,13 @@ void GUI::actMouse(Frame& frame, float delta, const CursorState& cursor) { pressed = nullptr; } - if (hover && !focusHappened) { + if (hover) { for (Mousecode code : MOUSECODES_ALL) { if (input.jclicked(code)) { hover->clicked(code); } } } - performClickOutside(frame, delta, cursorPos); -} - -void GUI::performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos) { - auto nodes = frame.getNodes(); - std::vector> activeNodes; - - for (const auto& node : nodes) { - if (node && node->isVisible() && node->isInteractive()) { - activeNodes.push_back(node); - } - } - - for (Mousecode code : {Mousecode::BUTTON_1, Mousecode::BUTTON_2, Mousecode::BUTTON_3}) { - if (input.jclicked(code)) { - bool isOverAnyNode = false; - for (const auto& node : activeNodes) { - if (node && node->isInside(cursorPos)) { - isOverAnyNode = true; - break; - } - } - if (!isOverAnyNode) { - for (const auto& node : activeNodes) { - if (node) { - node->clickedOutside(code); - } - } - } - } - } } void GUI::actFocused() { diff --git a/src/graphics/ui/GUI.hpp b/src/graphics/ui/GUI.hpp index 9b65089c1..97fc0ed37 100644 --- a/src/graphics/ui/GUI.hpp +++ b/src/graphics/ui/GUI.hpp @@ -2,6 +2,7 @@ #include "delegates.hpp" +#include #include #include #include @@ -92,7 +93,6 @@ namespace gui { bool debug = false; void actMouse(Frame& frame, float delta, const CursorState& cursor); - void performClickOutside(Frame& frame, float delta, glm::vec2 cursorPos); void actFocused(); void updateTooltip(float delta); void resetTooltip(); diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index e99a86d33..395c8d34e 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -16,7 +16,6 @@ #include "graphics/ui/GUI.hpp" #include "items/Inventory.hpp" #include "items/ItemDef.hpp" -#include "items/ItemStack.hpp" #include "logic/scripting/scripting.hpp" #include "maths/voxmaths.hpp" #include "objects/Player.hpp" @@ -608,33 +607,6 @@ void InventoryView::setPos(const glm::vec2& pos) { Container::setPos(pos - origin); } -void InventoryView::clickedOutside(Mousecode button) { - // root is the id of the main inventory - if (getId() != "root") { - return; - } - int mode; - if (button == Mousecode::BUTTON_1) { - mode = 0; - } else if (button == Mousecode::BUTTON_2) { - mode = 1; - } else if (button == Mousecode::BUTTON_3) { - mode = 2; - } else { - return; - }; - auto exchangeSlot = std::dynamic_pointer_cast( - gui.get(SlotView::EXCHANGE_SLOT_NAME)); - if (exchangeSlot == nullptr) { - return; - } - ItemStack& grabbed = exchangeSlot->getStack(); - if (grabbed.isEmpty()) { - return; - } - scripting::on_inventory_clicked_outside(exchangeSlot->getInventoryId(), 0, mode); -} - void InventoryView::setOrigin(const glm::vec2& origin) { this->origin = origin; } diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index a0d3c76e9..243d8b6b5 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -143,8 +143,6 @@ namespace gui { void setSelected(int index); - void clickedOutside(Mousecode button) override; - void bind( const std::shared_ptr& inventory, const Content* content diff --git a/src/graphics/ui/elements/UINode.hpp b/src/graphics/ui/elements/UINode.hpp index bd2254567..fb699a737 100644 --- a/src/graphics/ui/elements/UINode.hpp +++ b/src/graphics/ui/elements/UINode.hpp @@ -207,9 +207,6 @@ namespace gui { virtual void onFocus(); virtual void doubleClick(int x, int y); virtual void click(int x, int y); - virtual void clickedOutside(Mousecode button) { - // Empty for all UINodes, except InventoryView - } virtual void clicked(Mousecode button); virtual void mouseMove(int x, int y) {}; virtual void mouseRelease(int x, int y); From 953a920e00751ace69d68065dfb80022af4b7d6a Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 01:14:54 +0500 Subject: [PATCH 5/8] add middleclick item dropping/duping --- src/frontend/hud.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 3a4557797..08a4b8455 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -180,6 +180,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player) R"()" ); From 39f7f29e88575b7cfdfbecaccf604006ec7b7a58 Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 01:28:40 +0500 Subject: [PATCH 6/8] fix: change ! to not --- res/content/base/modules/util.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/content/base/modules/util.lua b/res/content/base/modules/util.lua index dbad0c2a1..4d25ccb91 100644 --- a/res/content/base/modules/util.lua +++ b/res/content/base/modules/util.lua @@ -9,7 +9,7 @@ function util.drop_from_slot(invid, slot, mode) return end local pid = hud.get_player() - if mode == 2 and !player.is_infinite_items(pid) then + if mode == 2 and not player.is_infinite_items(pid) then return end local itemid, itemcount = inventory.get(invid, slot) From 6a486af6abb9dfd4fe1afb7c79c28194057125d9 Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 01:46:35 +0500 Subject: [PATCH 7/8] add docs for get_exchange_inventory --- doc/en/scripting/builtins/libhud.md | 4 ++++ doc/ru/scripting/builtins/libhud.md | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/en/scripting/builtins/libhud.md b/doc/en/scripting/builtins/libhud.md index 1d6264b2d..550659ccc 100644 --- a/doc/en/scripting/builtins/libhud.md +++ b/doc/en/scripting/builtins/libhud.md @@ -57,6 +57,10 @@ hud.get_block_inventory() -> int -- Gives the ID of the second open inventory (block, virtual inventory...) or 0. hud.get_second_inventory() -> int +-- Get the inventory ID of exchange item (grabbed item in inventory) or 0. +-- It has only one slot - 0 +hud.get_exchange_inventory() -> int + -- Gives the ID of the player that the UI is bound to. hud.get_player() -> int diff --git a/doc/ru/scripting/builtins/libhud.md b/doc/ru/scripting/builtins/libhud.md index bad0e93c6..7a93c93e4 100644 --- a/doc/ru/scripting/builtins/libhud.md +++ b/doc/ru/scripting/builtins/libhud.md @@ -58,6 +58,11 @@ hud.get_block_inventory() -> int -- Дает ID второго открытого инвентаря (блок, виртуальный инвентарь...) или 0. hud.get_second_inventory() -> int +-- Получить ID инвентаря, в котором находится предмет во время +-- его перемещения в инвентаре, или 0 если его не существует. +-- Имеет единственный слот - 0 +hud.get_exchange_inventory() -> int + -- Дает ID игрока, к которому привязан пользовательский интерфейс. hud.get_player() -> int @@ -81,4 +86,4 @@ hud.set_allow_pause(flag: boolean) -- Функция, управляющая именованным скелетом 'hand' (см. gfx.skeletons) hud.hand_controller: function() -``` \ No newline at end of file +``` From 1d19dac5ce7f057e6d8485b18acfdcd105950481 Mon Sep 17 00:00:00 2001 From: neveix Date: Fri, 14 Aug 2026 02:10:55 +0500 Subject: [PATCH 8/8] delete redundant scripting events --- src/logic/scripting/scripting.hpp | 1 - src/logic/scripting/scripting_hud.cpp | 17 ----------------- 2 files changed, 18 deletions(-) diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index a4f6adc83..0044213cd 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -109,7 +109,6 @@ namespace scripting { void on_inventory_open(const Player* player, const Inventory& inventory); void on_inventory_closed(const Player* player, const Inventory& inventory); void on_inventory_interact(int invid, int slot, int action, int mode); - void on_inventory_clicked_outside(int exchange_invid, int exchange_slot, int mode); void on_player_tick(Player* player, int tps); diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index 92ba4e4ca..59b928d21 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -110,22 +110,6 @@ void scripting::on_inventory_interact(int invid, int slot, int action, int mode) } } -void scripting::on_inventory_clicked_outside(int exchange_invid, int exchange_slot, int mode) { - auto L = lua::get_main_state(); - for (auto& pack : content_control->getAllContentPacks()) { - lua::emit_event( - L, - pack.id + ":.inventoryclickedoutside", - [&](lua::State* L) { - lua::pushinteger(L, exchange_invid); - lua::pushinteger(L, exchange_slot); - lua::pushinteger(L, mode); - return 3; - } - ); - } -} - void scripting::load_hud_script( const scriptenv& senv, const std::string& packid, @@ -143,7 +127,6 @@ void scripting::load_hud_script( register_event(env, "on_hud_render", packid + ":.hudrender"); register_event(env, "on_hud_close", packid + ":.hudclose"); register_event(env, "on_inventory_interact", packid + ":.inventoryinteract"); - register_event(env, "on_inventory_clicked_outside", packid + ":.inventoryclickedoutside"); } gui::PageLoaderFunc scripting::create_page_loader() {