Inventory enhancements #897: 2, 5, 9, 11, 12 (#931)

* implement a bit

* change shift to ctrl

* add enhancement #2

* add ctrl-interaction with content access

* fix libinventory.move bug (none checking)

* fix p.5

* move shareinv logic into inventory_utils

* add inventory utils

* small refactor

* fix iframe.src = ""

---------

Co-authored-by: MihailRis <mexaruc@gmail.com>
This commit is contained in:
Neveix 2026-08-14 23:25:42 +05:00 • committed by GitHub
parent f8e4e2759b
commit 3b3bf8e878
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 84 additions and 37 deletions

View file

@ -1,4 +1,4 @@
<inventory>
<slots-grid pos="0, 164" rows="1" count="10" sharefunc="inventory_share_func"/>
<slots-grid rows="3" start-index="10" count="30" sharefunc="inventory_share_func"/>
<slots-grid pos="0, 164" rows="1" count="10" sharefunc="share_func"/>
<slots-grid rows="3" start-index="10" count="30" sharefunc="share_func"/>
</inventory>

View file

@ -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

View file

@ -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

View file

@ -106,6 +106,7 @@ std::shared_ptr<UINode> HudElement::getNode() const {
std::shared_ptr<InventoryView> 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<InventoryView> 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);

View file

@ -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);

View file

@ -123,6 +123,8 @@ namespace gui {
SHARE = 2,
UNDEFINED,
};
private:
void actIfCannotPut(ItemStack& stack, ItemStack& grabbed, InteractionAction& action);
};
class InventoryView final : public gui::Container {

View file

@ -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) {

View file

@ -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);

View file

@ -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) {