2015-11-21 20:05:45 +03:00
|
|
|
---
|
|
|
|
title: Inventories
|
|
|
|
layout: default
|
2018-07-15 21:36:35 +03:00
|
|
|
root: ../..
|
2018-07-15 17:28:10 +03:00
|
|
|
idx: 5.2
|
2018-07-15 21:13:16 +03:00
|
|
|
redirect_from: /en/chapters/inventories.html
|
2015-11-21 20:05:45 +03:00
|
|
|
---
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
|
2018-05-01 05:08:59 +03:00
|
|
|
In this chapter you will learn how to use and manipulate inventories, whether
|
|
|
|
that is a player inventory, a node inventory, or a detached inventory.
|
2015-11-21 20:05:45 +03:00
|
|
|
This chapter assumes that you already know how to create and manipulate
|
|
|
|
[ItemStacks](itemstacks.html).
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
* [Basic Concepts](#basic-concepts)
|
|
|
|
* [Types of Inventories](#types-of-inventories)
|
|
|
|
* [Player Inventories](#player-inventories)
|
|
|
|
* [Node Inventories](#node-inventories)
|
|
|
|
* [Detached Inventories](#detached-inventories)
|
|
|
|
* [InvRef and Lists](#invref-and-lists)
|
|
|
|
* [Inventory Location](#inventory-location)
|
2017-10-15 04:52:53 +03:00
|
|
|
* [List Sizes](#list-sizes)
|
2017-09-20 01:59:04 +03:00
|
|
|
* [Empty Lists](#empty-lists)
|
|
|
|
* [Lua Tables](#lua-tables)
|
|
|
|
* [Lua Tables for Lists](#lua-tables-for-lists)
|
|
|
|
* [InvRef, Items and Stacks](#invref-items-and-stacks)
|
|
|
|
* [Adding to a List](#adding-to-a-list)
|
|
|
|
* [Checking for Room](#checking-for-room)
|
|
|
|
* [Taking Items](#taking-items)
|
|
|
|
* [Checking Inventory Contents](#checking-inventory-contents)
|
|
|
|
* [Manipulating Stacks](#manipulating-stacks)
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
## Basic Concepts
|
|
|
|
|
|
|
|
Components of an inventory:
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
* An **inventory** is a collection of **inventory list**s, which are simply called **list**s in the context of inventories.
|
|
|
|
* An **inventory list** is an array of **slot**s. (An array is a table indexed by numbers).
|
|
|
|
* A **slot** contains a stack which may or may not be empty.
|
2015-11-21 20:05:45 +03:00
|
|
|
* An **InvRef** is an object that represents an inventory, and has functions to manipulate it.
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
## Types of Inventories
|
|
|
|
|
|
|
|
There are three types of inventory:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
* **Player Inventories**: An inventory attached to a player.
|
|
|
|
* **Node Inventories**: An inventory attached to a node.
|
|
|
|
* **Detached Inventories**: An inventory which is not attached to a node or player.
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
<figure>
|
2018-07-15 21:36:35 +03:00
|
|
|
<img src="{{ page.root }}//static/inventories_lists.png" alt="The player inventory formspec, with annotated list names.">
|
2017-08-26 21:01:51 +03:00
|
|
|
<figcaption>
|
|
|
|
This image shows the two inventories visible when you press i.
|
|
|
|
The gray boxes are inventory lists.<br />
|
2018-05-01 05:08:59 +03:00
|
|
|
The creative inventory, left (in red) is detached and is made up of a
|
2017-08-26 21:01:51 +03:00
|
|
|
single list.<br />
|
|
|
|
The player inventory, right (in blue) is a player inventory
|
|
|
|
and is made up of three lists.<br />
|
|
|
|
Note that the trash can is a <a href="formspecs.html">formspec</a>
|
|
|
|
element, and is not part of the inventory.
|
|
|
|
</figcaption>
|
2015-11-21 20:05:45 +03:00
|
|
|
</figure>
|
|
|
|
|
2017-10-15 04:52:53 +03:00
|
|
|
### Player Inventories
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
A player inventory usually has two grids, one for the main inventory and one for crafting.
|
2018-07-15 17:28:10 +03:00
|
|
|
Press i in game to see your player inventory.
|
2017-09-20 01:59:04 +03:00
|
|
|
|
|
|
|
Use a player's name to get their inventory:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local inv = minetest.get_inventory({type="player", name="celeron55"})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-10-15 04:52:53 +03:00
|
|
|
### Node Inventories
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
A node inventory is related to the position of a specific node, such as a chest.
|
|
|
|
The node must be loaded, because it is stored in [node metadata](node_metadata.html).
|
|
|
|
|
|
|
|
Use its position to get a node inventory:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local inv = minetest.get_inventory({type="node", pos={x=, y=, z=}})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
### Detached Inventories
|
|
|
|
|
|
|
|
A detached inventory is independent of players and nodes.
|
2017-09-20 01:59:04 +03:00
|
|
|
One example of a detached inventory is the creative inventory. It is detached from
|
|
|
|
any specific player because all players see the same creative inventory.
|
|
|
|
A detached inventory would also allow multiple chests to share the same inventory.
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
Use the inventory name to get a detached inventory:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local inv = minetest.get_inventory({type="detached", name="inventory_name"})
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can create your own detached inventories:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
minetest.create_detached_inventory("inventory_name", callbacks)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
This creates a detached inventory or, if the inventory already exists, it is cleared.
|
2018-07-15 21:36:35 +03:00
|
|
|
You can also supply a [table of callbacks]({{ page.root }}/lua_api.html#detached-inventory-callbacks).
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
## InvRef and Lists
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Inventory Location
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can check where an inventory is located:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local location = inv:get_location()
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
This will return a table like the one passed to `minetest.get_inventory()`.
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
If the location is unknown, `{type="undefined"}` is returned.
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### List Sizes
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
Inventory lists have a size, for example `main` has size of 32 slots by default.
|
|
|
|
They also have a width, which is used to divide them into a grid.
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
if inv:set_size("main", 32) then
|
2017-08-26 21:01:51 +03:00
|
|
|
inv:set_width("main", 8)
|
|
|
|
print("size: " .. inv.get_size("main"))
|
|
|
|
print("width: " .. inv:get_width("main"))
|
2015-11-21 20:05:45 +03:00
|
|
|
else
|
2017-08-26 21:01:51 +03:00
|
|
|
print("Error!")
|
2015-11-21 20:05:45 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
<!--The width and height of an inventory in a [formspec](formspecs.html) is
|
|
|
|
determined by the formspec element, not by the inventory. By that I mean
|
|
|
|
a list doesn't have a width or height, only the maximum number of stacks/slots.-->
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Empty Lists
|
|
|
|
|
|
|
|
You can use `list_is_empty` to check if a list is empty:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
if inv:is_empty("main") then
|
2017-08-26 21:01:51 +03:00
|
|
|
print("The list is empty!")
|
2015-11-21 20:05:45 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
### Lua Tables
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can convert an inventory to a Lua table:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local lists = inv:get_lists()
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
The table will be in this form:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
{
|
2017-08-26 21:01:51 +03:00
|
|
|
list_one = {
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
-- inv:get_size("list_one") elements
|
|
|
|
},
|
|
|
|
list_two = {
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
-- inv:get_size("list_two") elements
|
|
|
|
}
|
2015-11-21 20:05:45 +03:00
|
|
|
}
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can then set the inventory:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
inv:set_lists(lists)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
Please note that the sizes of lists will not change.
|
|
|
|
|
|
|
|
### Lua Tables for Lists
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can do the above for individual lists:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local list = inv:get_list("list_one")
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
It will be in this form:
|
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
{
|
2017-08-26 21:01:51 +03:00
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
ItemStack,
|
|
|
|
-- inv:get_size("list_one") elements
|
2015-11-21 20:05:45 +03:00
|
|
|
}
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can then set the list:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
inv:set_list("list_one", list)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
|
|
|
Please note that the sizes of lists will not change.
|
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
## InvRef, Items and Stacks
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Adding to a List
|
|
|
|
|
|
|
|
To add items to a list named `"main"`:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local stack = ItemStack("default:stone 99")
|
|
|
|
local leftover = inv:add_item("main", stack)
|
|
|
|
if leftover:get_count() > 0 then
|
2017-08-26 21:01:51 +03:00
|
|
|
print("Inventory is full! " .. leftover:get_count() .. " items weren't added")
|
2015-11-21 20:05:45 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Checking for Room
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
To check whether a list has room for items:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
if not inv:room_for_item("main", stack) then
|
2017-08-26 21:01:51 +03:00
|
|
|
print("Not enough room!")
|
2015-11-21 20:05:45 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Taking Items
|
|
|
|
|
|
|
|
To remove items from a list:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local taken = inv:remove_item("main", stack)
|
|
|
|
print("Took " .. taken:get_count())
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Checking Inventory Contents
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
To check whether an inventory contains a specific quantity of an item:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
if not inv:contains_item(listname, stack) then
|
2017-08-26 21:01:51 +03:00
|
|
|
print("Item not in inventory!")
|
2015-11-21 20:05:45 +03:00
|
|
|
end
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
This works if the item count is split up over multiple stacks.
|
|
|
|
For example checking for "default:stone 200" will work if there
|
|
|
|
are stacks of 99 + 95 + 6.
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
### Manipulating Stacks
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2017-09-20 01:59:04 +03:00
|
|
|
You can manipulate individual stacks:
|
2015-11-21 20:05:45 +03:00
|
|
|
|
2018-09-19 14:04:51 +03:00
|
|
|
```lua
|
2015-11-21 20:05:45 +03:00
|
|
|
local stack = inv:get_stack(listname, 0)
|
|
|
|
inv:set_stack(listname, 0, stack)
|
2018-09-19 14:04:51 +03:00
|
|
|
```
|