diff --git a/res/layouts/inventory.xml b/res/layouts/inventory.xml index 4291ab4d3..7a33b054f 100644 --- a/res/layouts/inventory.xml +++ b/res/layouts/inventory.xml @@ -1,4 +1,4 @@ - - + + diff --git a/res/layouts/inventory.xml.lua b/res/layouts/inventory.xml.lua index 9f836223d..5c79db6ff 100644 --- a/res/layouts/inventory.xml.lua +++ b/res/layouts/inventory.xml.lua @@ -1,12 +1 @@ -function inventory_share_func(invid, slotid) - local blockinv = hud.get_block_inventory() - if blockinv ~= 0 then - inventory.move(invid, slotid, blockinv) - elseif rules.get("allow-content-access") then - inventory.set(invid, slotid, 0, 0) - elseif slotid < 10 then - inventory.move_range(invid, slotid, invid, 10) - else - inventory.move_range(invid, slotid, invid, 0, 9) - end -end +share_func = require("core:inventory_utils").share_default_func diff --git a/res/modules/inventory_utils.lua b/res/modules/inventory_utils.lua new file mode 100644 index 000000000..17089cdab --- /dev/null +++ b/res/modules/inventory_utils.lua @@ -0,0 +1,21 @@ +local M = {} + +function M.share_default_func(invid, slotid) + local blockinv = hud.get_block_inventory() + local playerinv = player.get_inventory(hud.get_player()) + if blockinv ~= 0 then + if invid == blockinv then + inventory.move(blockinv, slotid, playerinv) + else + inventory.move(invid, slotid, blockinv) + end + elseif rules.get("allow-content-access") then + inventory.set(invid, slotid, 0, 0) + elseif slotid < 10 then + inventory.move_range(invid, slotid, invid, 10) + else + inventory.move_range(invid, slotid, invid, 0, 9) + end +end + +return M diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 08a4b8455..6751b885c 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -106,6 +106,7 @@ std::shared_ptr HudElement::getNode() const { std::shared_ptr Hud::createContentAccess() { auto& content = frontend.getLevel().content; auto& indices = *content.getIndices(); + auto& input = this->input; auto inventory = player.getInventory(); size_t itemsCount = indices.items.count(); @@ -115,12 +116,19 @@ std::shared_ptr Hud::createContentAccess() { } SlotLayout slotLayout(-1, glm::vec2(), false, true, nullptr, - [inventory, &indices](uint, ItemStack& item) { + [inventory, &indices, &input](uint, ItemStack& item) { auto copy = ItemStack(item); + if (input.pressed(Keycode::LEFT_CONTROL)) { + copy.maximizeCount(indices); + } inventory->move(copy, indices); }, - [this, inventory](uint, ItemStack& item) { - inventory->getSlot(player.getChosenSlot()).set(item); + [this, inventory, &indices, &input](uint, ItemStack& item) { + auto copy = ItemStack(item); + if (input.pressed(Keycode::LEFT_CONTROL)) { + copy.maximizeCount(indices); + } + inventory->getSlot(player.getChosenSlot()).set(copy); }); InventoryBuilder builder(gui); diff --git a/src/graphics/ui/elements/InventoryView.cpp b/src/graphics/ui/elements/InventoryView.cpp index 395c8d34e..614d4c913 100644 --- a/src/graphics/ui/elements/InventoryView.cpp +++ b/src/graphics/ui/elements/InventoryView.cpp @@ -366,28 +366,12 @@ void SlotView::performLeftClick(ItemStack& stack, ItemStack& grabbed) { ); return; } - + auto indices = *content->getIndices(); if (!layout.itemSource && stack.accepts(grabbed) && layout.placing) { action = InteractionAction::PUT; - stack.move(grabbed, *content->getIndices()); + stack.move(grabbed, indices); } else { - if (layout.itemSource) { - if (grabbed.isEmpty()) { - action = InteractionAction::TAKE; - grabbed.set(stack); - } else { - action = InteractionAction::PUT; - grabbed.clear(); - } - } else if (grabbed.isEmpty()) { - if (layout.taking) { - action = InteractionAction::TAKE; - std::swap(grabbed, stack); - } - } else if (layout.taking && layout.placing) { - action = InteractionAction::PUT; - std::swap(grabbed, stack); - } + actIfCannotPut(stack, grabbed, action); } if (action != InteractionAction::UNDEFINED) { @@ -400,6 +384,39 @@ 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(); + if (layout.itemSource) { + if (grabbed.isEmpty()) { + action = InteractionAction::TAKE; + grabbed.set(stack); + if (input.pressed(Keycode::LEFT_CONTROL)) { + grabbed.maximizeCount(*content->getIndices()); + } + } else { + if (grabbed.accepts(stack)) { + auto& def = indices.items.require(stack.getItemId()); + if (grabbed.getCount() < def.stackSize) { + action = InteractionAction::TAKE; + grabbed.setCount(grabbed.getCount() + 1); + } + } else { + action = InteractionAction::PUT; + grabbed.clear(); + } + } + } else if (grabbed.isEmpty()) { + if (layout.taking) { + action = InteractionAction::TAKE; + std::swap(grabbed, stack); + } + } else if (layout.taking && layout.placing) { + action = InteractionAction::PUT; + std::swap(grabbed, stack); + } +} + void SlotView::performRightClick(ItemStack& stack, ItemStack& grabbed) { if (layout.rightClick) { layout.rightClick(inventoryId, stack); diff --git a/src/graphics/ui/elements/InventoryView.hpp b/src/graphics/ui/elements/InventoryView.hpp index 243d8b6b5..fbfe3eee9 100644 --- a/src/graphics/ui/elements/InventoryView.hpp +++ b/src/graphics/ui/elements/InventoryView.hpp @@ -123,6 +123,8 @@ namespace gui { SHARE = 2, UNDEFINED, }; + private: + void actIfCannotPut(ItemStack& stack, ItemStack& grabbed, InteractionAction& action); }; class InventoryView final : public gui::Container { diff --git a/src/items/ItemStack.cpp b/src/items/ItemStack.cpp index f99d8700a..d0f39d5fe 100644 --- a/src/items/ItemStack.cpp +++ b/src/items/ItemStack.cpp @@ -48,6 +48,14 @@ void ItemStack::setCount(itemcount_t count) { } } +void ItemStack::maximizeCount(const ContentIndices& indices) { + auto& def = indices.items.require(getItemId()); + this->count = def.stackSize; + if (count == 0) { + clear(); + } +} + void ItemStack::setField(std::string_view name, dv::value value) { if (fields == nullptr) { if (value == nullptr) { diff --git a/src/items/ItemStack.hpp b/src/items/ItemStack.hpp index 4896bc39e..1ec3fe41d 100644 --- a/src/items/ItemStack.hpp +++ b/src/items/ItemStack.hpp @@ -18,6 +18,7 @@ public: void set(const ItemStack& item); void set(ItemStack&& item); void setCount(itemcount_t count); + void maximizeCount(const ContentIndices& indices); /// @brief Set a field in the item stack data. void setField(std::string_view name, dv::value value); diff --git a/src/logic/scripting/lua/libs/libinventory.cpp b/src/logic/scripting/lua/libs/libinventory.cpp index 2aea52394..9d11d66c6 100644 --- a/src/logic/scripting/lua/libs/libinventory.cpp +++ b/src/logic/scripting/lua/libs/libinventory.cpp @@ -2,6 +2,7 @@ #include "items/Inventories.hpp" #include "items/ItemStack.hpp" #include "logic/BlocksController.hpp" +#include "logic/scripting/lua/lua_util.hpp" #include "world/Level.hpp" #include "api_lua.hpp" @@ -180,7 +181,7 @@ static int l_move(lua::State* L) { validate_slotid(slotAid, invA); auto invBid = lua::tointeger(L, 3); - auto slotBid = lua::isnil(L, 4) ? -1 : lua::tointeger(L, 4); + auto slotBid = lua::isnoneornil(L, 4) ? -1 : lua::tointeger(L, 4); auto& invB = get_inventory(invBid, 3); auto& slot = invA.getSlot(slotAid); if (slotBid == -1) {