diff --git a/res/content/base/scripts/hud.lua b/res/content/base/scripts/hud.lua index 5d3bfeb46..b936e5fb6 100644 --- a/res/content/base/scripts/hud.lua +++ b/res/content/base/scripts/hud.lua @@ -10,6 +10,31 @@ function on_hud_open() end) base_util.drop_from_slot(pid, invid, 0, mode, dir_shift) end) + + events.on("core:access_panel_slot_middle_click", function(itemid) + local exc_invid = hud.get_exchange_inventory() + inventory.set(exc_invid, 0, itemid, item.stack_size(itemid)) + end) + + events.on("core:slot_middle_click", function(invid, slot) + if not player.is_infinite_items(hud.get_player()) then + return + end + local exc_invid = hud.get_exchange_inventory() + local exc_itemid = inventory.get(exc_invid, 0) + local itemid = inventory.get(invid, slot) + if itemid == 0 and exc_itemid ~= 0 then + local stack_size = item.stack_size(exc_itemid) + inventory.set(invid, slot, exc_itemid, stack_size) + elseif exc_itemid == 0 then + local stack_size = item.stack_size(itemid) + inventory.set(exc_invid, 0, itemid, stack_size) + elseif exc_itemid == itemid then + local stack_size = item.stack_size(exc_itemid) + inventory.set(invid, slot, exc_itemid, stack_size) + end + end) + input.add_callback("player.drop", function() if hud.is_paused() or hud.is_inventory_open() then return diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 614d4c913..61403cad0 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -366,10 +366,16 @@ void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) { ); return; } - auto indices = *content->getIndices(); + auto& indices = *content->getIndices(); if (!layout.itemSource && stack.accepts(grabbed) && layout.placing) { - action = InteractionAction::PUT; - stack.move(grabbed, indices); + auto& def = indices.items.require(stack.getItemId()); + if (stack.getCount() < def.stackSize) { + action = InteractionAction::PUT; + stack.move(grabbed, indices); + } else { + action = InteractionAction::TAKE; + std::swap(grabbed, stack); + } } else { actIfCannotPut(stack, grabbed, action); } @@ -386,13 +392,13 @@ void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) { void SlotView::actIfCannotPut(ItemStack& stack, ItemStack& grabbed, InteractionAction& action) { const auto& input = gui.getInput(); - auto indices = *content->getIndices(); + auto& indices = *content->getIndices(); if (layout.itemSource) { if (grabbed.isEmpty()) { action = InteractionAction::TAKE; grabbed.set(stack); if (input.pressed(Keycode::LEFT_CONTROL)) { - grabbed.maximizeCount(*content->getIndices()); + grabbed.maximizeCount(indices); } } else { if (grabbed.accepts(stack)) { @@ -500,6 +506,17 @@ void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) { ); } +void SlotView::performMiddleClick(ItemStack& stack, ItemStack& grabbed) { + if (layout.itemSource) { + scripting::on_access_panel_slot_middle_click(stack.getItemId()); + } else { + scripting::on_slot_middle_click( + inventoryId, + layout.index + ); + } +} + void SlotView::clicked(Mousecode button) { if (bound == nullptr) return; auto exchangeSlot = @@ -514,6 +531,8 @@ void SlotView::clicked(Mousecode button) { performLeftClick(stack, grabbed); } else if (button == Mousecode::BUTTON_2) { performRightClick(stack, grabbed); + } else if (button == Mousecode::BUTTON_3) { + performMiddleClick(stack, grabbed); } if (layout.updateFunc) { diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index fbfe3eee9..b8e16cc44 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -67,6 +67,7 @@ namespace gui { void performLeftClick(ItemStack& stack, ItemStack& grabbed); void performRightClick(ItemStack& stack, ItemStack& grabbed); + void performMiddleClick(ItemStack& stack, ItemStack& grabbed); void drawItemIcon( Batch2D& batch, diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index 116226aff..64b232dc0 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -113,6 +113,9 @@ namespace scripting { void on_inventory_closed(const Player* player, const Inventory& inventory); void on_inventory_interact(int invid, int slot, int action, int mode); + void on_slot_middle_click(int invid, int slot); + void on_access_panel_slot_middle_click(const itemid_t itemid); + void on_player_tick(Player* player, int tps); /// @brief Called on RMB click with the item selected diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index dcd310e37..4befdd221 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -12,6 +12,7 @@ #include "lua/libs/api_lua.hpp" #include "lua/lua_engine.hpp" #include "scripting.hpp" +#include "typedefs.hpp" using namespace scripting; @@ -109,6 +110,31 @@ void scripting::on_inventory_interact(int invid, int slot, int action, int mode) } } +void scripting::on_slot_middle_click(int invid, int slot) { + auto L = lua::get_main_state(); + lua::emit_event( + L, + "core:slot_middle_click", + [&](lua::State* L) { + lua::pushinteger(L, invid); + lua::pushinteger(L, slot); + return 2; + } + ); +} + +void scripting::on_access_panel_slot_middle_click(const itemid_t itemid) { + auto L = lua::get_main_state(); + lua::emit_event( + L, + "core:access_panel_slot_middle_click", + [&](lua::State* L) { + lua::pushinteger(L, itemid); + return 1; + } + ); +} + void scripting::load_hud_script( const scriptenv& senv, const std::string& packid,