Skip to content

Commit

Permalink
Implement metadata-aware version of InvRef:remove_item()
Browse files Browse the repository at this point in the history
  • Loading branch information
andriyndev committed Feb 9, 2025
1 parent e6cf081 commit c22e6ce
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 10 deletions.
9 changes: 4 additions & 5 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7850,11 +7850,10 @@ An `InvRef` is a reference to an inventory.
the stack of items can be fully taken from the list.
If `match_meta` is false, only the items' names are compared
(default: `false`).
* `remove_item(listname, stack)`: take as many items as specified from the
list, returns the items that were actually removed (as an `ItemStack`)
-- note that any item metadata is ignored, so attempting to remove a specific
unique item this way will likely remove the wrong one -- to do that use
`set_stack` with an empty `ItemStack`.
* `remove_item(listname, stack, [match_meta])`: take as many items as specified from the
list, returns the items that were actually removed (as an `ItemStack`).
If `match_meta` is `true`, the function also takes metadata into account
(since version `5.11.0`).
* `get_location()`: returns a location compatible to
`core.get_inventory(location)`.
* returns `{type="undefined"}` in case location is not known
Expand Down
4 changes: 2 additions & 2 deletions src/inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,11 +693,11 @@ bool InventoryList::containsItem(const ItemStack &item, bool match_meta) const
return false;
}

ItemStack InventoryList::removeItem(const ItemStack &item)
ItemStack InventoryList::removeItem(const ItemStack &item, bool match_meta)
{
ItemStack removed;
for (auto i = m_items.rbegin(); i != m_items.rend(); ++i) {
if (i->name == item.name) {
if (i->name == item.name && (!match_meta || (i->metadata == item.metadata))) {
u32 still_to_remove = item.count - removed.count;
ItemStack leftover = removed.addItem(i->takeItem(still_to_remove),
m_itemdef);
Expand Down
2 changes: 1 addition & 1 deletion src/inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class InventoryList
// If not as many items exist as requested, removes as
// many as possible.
// Returns the items that were actually removed.
ItemStack removeItem(const ItemStack &item);
ItemStack removeItem(const ItemStack &item, bool match_meta);

// Takes some items from a slot.
// If there are not enough, takes as many as it can.
Expand Down
7 changes: 5 additions & 2 deletions src/script/lua_api/l_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ int InvRef::l_contains_item(lua_State *L)
return 1;
}

// remove_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
// remove_item(self, listname, itemstack or itemstring or table or nil, [match_meta]) -> itemstack
// Returns the items that were actually removed
int InvRef::l_remove_item(lua_State *L)
{
Expand All @@ -339,8 +339,11 @@ int InvRef::l_remove_item(lua_State *L)
const char *listname = luaL_checkstring(L, 2);
ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
bool match_meta = false;
if (lua_isboolean(L, 4))
match_meta = readParam<bool>(L, 4);
if(list){
ItemStack removed = list->removeItem(item);
ItemStack removed = list->removeItem(item, match_meta);
if(!removed.empty())
reportInventoryChange(L, ref);
LuaItemStack::create(L, removed);
Expand Down

0 comments on commit c22e6ce

Please sign in to comment.