2022-08-16 01:05:44 +03:00
---
title: ItemStacks und Inventare
layout: default
root: ../..
idx: 2.4
description: Manipuliere InvRefs und ItemStacks
redirect_from:
- /de/chapters/inventories.html
- /de/chapters/itemstacks.html
- /de/inventories/inventories.html
- /de/inventories/itemstacks.html
---
## Einleitung <!-- omit in toc -->
2022-08-18 18:58:38 +03:00
In diesem Kapitel werden Sie lernen, wie man Inventare verwendet und manipuliert, egal
ob es sich um ein Spielerinventar, ein Blockinventar oder ein freistehendes Inventar handelt.
2022-08-16 01:05:44 +03:00
- [Was sind ItemStacks und Inventare? ](#was-sind-itemstacks-und-inventare )
- [ItemStacks ](#itemstacks )
- [Inventarstandorte ](#inventarstandorte )
2022-08-16 14:34:53 +03:00
- [Listen ](#listen )
- [Größe und Breite ](#größe-und-breite )
- [Inhalt überprüfen ](#inhalt-überprüfen )
- [Ändern von Inventaren und ItemStacks ](#ändern-von-inventaren-und-itemstacks )
- [Zu einer Liste hinzufügen ](#zu-einer-liste-hinzufügen )
- [Items nehmen ](#items-nehmen )
2022-08-18 18:58:38 +03:00
- [Stacks manipulieren ](#stacks-manipulieren )
2022-08-16 14:34:53 +03:00
- [Abnutzung ](#abnutzung )
- [Lua Tabellen ](#lua-tabellen )
2022-08-16 01:05:44 +03:00
## Was sind ItemStacks und Inventare?
Ein ItemStack sind die Daten hinter einer einzelnen Zelle in einem Inventar.
Ein *Inventar* ist eine Sammlung von *Inventarlisten* , von denen jede
ein 2D-Gitter aus ItemStacks ist.
Inventarlisten werden im Kontext von Inventaren einfach *Listen* genannt.
Der Sinn eines Inventars ist es, mehrere Raster zu ermöglichen, wenn Spieler
und Blöcke nur maximal ein Inventar haben.
## ItemStacks
ItemStacks haben vier Komponenten: name, count, wear und metadata.
Der Itemname kann der Itemname eines registrierten Items, ein Alias oder ein
unbekannter Itemname sein.
Unbekannte Items treten häufig auf, wenn Benutzer Mods deinstallieren oder wenn Mods
Items ohne Vorsichtsmaßnahmen entfernen, z. B. durch die Registrierung von Aliasen.
```lua
print(stack:get_name())
stack:set_name("default:dirt")
if not stack:is_known() then
print("Ist ein unbekanntes Item!")
end
```
Der Anzahl wird immer 0 oder größer sein.
Bei normalem Spielverlauf sollte die Anzahl nicht größer sein als die maximale
Stackgröße des Gegenstands - `stack_max` .
Allerdings können Admin-Befehle und fehlerhafte Mods dazu führen, dass Stacks die maximale Größe überschreiten.
```lua
print(stack:get_stack_max())
```
Ein ItemStack kann leer sein, in diesem Fall ist die Anzahl 0.
```lua
print(stack:get_count())
stack:set_count(10)
```
ItemStacks können auf verschiedene Weise mit der Funktion ItemStack konstruiert werden.
```lua
ItemStack() -- name="", count=0
ItemStack("default:pick_stone") -- count=1
ItemStack("default:stone 30")
ItemStack({ name = "default:wood", count = 10 })
```
Item-Metadaten sind ein unbegrenzter Schlüssel-Wert-Speicher für Daten über das Item.
Schlüssel-Wert bedeutet, dass Sie einen Namen (den sogenannten key) verwenden, um auf die Daten (den sogenannten value) zuzugreifen.
Einige Schlüssel haben eine besondere Bedeutung, wie z. B. `Beschreibung` , die verwendet wird, um eine pro Stack
Beschreibung.
Dies wird im Kapitel über Metadaten und Speicherung ausführlicher behandelt.
## Inventarstandorte
Ein Inventarstandort ist der Ort und die Art und Weise, wie das Inventar gespeichert wird.
Es gibt drei Arten von Inventarstandorten: Spieler, Blöcke und freistehend.
Ein Inventar ist direkt an einen und nur einen Ort gebunden - eine Aktualisierung des
Inventars wird es sofort aktualisieren.
Blockinventare beziehen sich auf die Position eines bestimmten Blockes, z. B. einer Truhe.
Der Block muss geladen werden, da er in den [Block-Metadaten ](../map/storage.html#metadata ) gespeichert ist.
```lua
local inv = minetest.get_inventory({ type="node", pos={x=1, y=2, z=3} })
```
Auf diese Weise erhält man eine *Inventar-Referenz* , allgemein als *InvRef* bezeichnet.
Inventar-Referenzen werden verwendet, um ein Inventar zu manipulieren.
*Referenz* bedeutet, dass die Daten nicht tatsächlich in diesem Objekt gespeichert sind,
sondern das Objekt aktualisiert die Daten direkt an Ort und Stelle.
Der Standort eines Inventarverweises kann wie folgt ermittelt werden:
```lua
local location = inv:get_location()
```
Spielerinventare können auf ähnliche Weise oder über eine Spielerreferenz abgerufen werden.
Der Spieler muss online sein, um auf sein Inventar zugreifen zu können.
```lua
local inv = minetest.get_inventory({ type="player", name="spieler1" })
-- oder
local inv = player:get_inventory()
```
Ein freistehendes Inventar ist ein Inventar, das unabhängig von Spielern oder Blöcken ist.
Freistehende Inventare werden auch nicht bei einem Neustart gespeichert.
```lua
local inv = minetest.get_inventory({
type="detached", name="inventar_name" })
```
Im Gegensatz zu den anderen Inventararten müssen Sie zunächst ein freistehendes Inventar erstellen
erstellen, bevor Sie darauf zugreifen:
```lua
minetest.create_detached_inventory("inventar_name")
```
Die Funktion create_detached_inventory akzeptiert 3 Argumente, wobei nur das erste -
der Inventarname - erforderlich ist.
Das zweite Argument nimmt eine Tabelle von Callbacks entgegen, die verwendet werden können,
um zu steuern, wie Spieler mit dem Inventar interagieren:
```lua
-- Eingabe nur freistehendes Inventar
minetest.create_detached_inventory("inventar_name", {
allow_move = function(inv, von_liste, von_index, zu_liste, zu_index, anzahl, player)
return anzahl -- erlaubt bewegen
end,
allow_put = function(inv, listenname, index, stack, spieler)
return stack:get_count() -- erlaubt setzen
end,
allow_take = function(inv, listenname, index, stack, spieler)
return 0 -- erlaubt es nicht zu nehmen
end,
on_put = function(inv, listenname, index, stack, spieler)
minetest.chat_send_all(spieler:get_player_name() ..
" gab " .. stack:to_string() ..
" zu der Spendenkiste von " .. minetest.pos_to_string(spieler:get_pos()))
end,
})
```
Berechtigungsaufrufe - d.h. diejenigen, die mit `allow_` beginnen - geben die Anzahl
der zu übertragenden Items zurück, wobei 0 verwendet wird, um die Übertragung vollständig zu verhindern.
Im Gegensatz dazu haben Aktionsrückrufe - beginnend mit `on_` - keinen Rückgabewert.
2022-08-16 14:34:53 +03:00
## Listen
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Inventarlisten sind ein Konzept, das es ermöglicht, mehrere Raster an einem einzigen Ort zu speichern.
Dies ist besonders nützlich für den Spieler, da es eine Reihe von allgemeinen Listen
gibt die alle Spiele haben, wie das *Hauptinventar* und die *Handwerksplätze* .
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
### Größe und Breite
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Listen haben eine Größe, die die Gesamtzahl der Zellen im Raster angibt, und eine
Breite, die nur innerhalb der Engine verwendet wird.
Die Breite der Liste wird beim Zeichnen des Inventars in einem Fenster nicht verwendet, denn der Code hinter dem Fenster bestimmt die zu verwendende Breite.
2022-08-16 01:05:44 +03:00
```lua
if inv:set_size("main", 32) then
inv:set_width("main", 8)
2022-08-16 14:34:53 +03:00
print("Größe: " .. inv:get_size("main"))
print("Breite: " .. inv:get_width("main"))
2022-08-16 01:05:44 +03:00
else
2022-08-16 14:34:53 +03:00
print("Fehler! Ungültiger itemname oder ungültige Größe für set_size()")
2022-08-16 01:05:44 +03:00
end
```
2022-08-16 14:34:53 +03:00
`set_size` wird fehlschlagen und false zurückgeben, wenn der Listenname oder die Größe ungültig ist.
Zum Beispiel kann die neue Größe zu klein sein, damit alle aktuellen Gegenstände
im Inventar zu passen.
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
### Inhalt überprüfen
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
`is_empty` kann benutzt werden, um zu sehen, ob eine Liste Items enthält:
2022-08-16 01:05:44 +03:00
```lua
if inv:is_empty("main") then
2022-08-16 14:34:53 +03:00
print("Die Liste ist leer!")
2022-08-16 01:05:44 +03:00
end
```
2022-08-16 14:34:53 +03:00
`contains_item` kann verwendet werden, um festzustellen, ob eine Liste ein bestimmtes Item enthält:
2022-08-16 01:05:44 +03:00
```lua
if inv:contains_item("main", "default:stone") then
2022-08-16 14:34:53 +03:00
print("Ich habe ein paar Steine gefunden!")
2022-08-16 01:05:44 +03:00
end
```
2022-08-16 14:34:53 +03:00
## Ändern von Inventaren und ItemStacks
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
### Zu einer Liste hinzufügen
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
`add_item` fügt Items zu einer Liste hinzu (in diesem Fall `"main"` ). Im folgenden
Beispiel, wird auch die maximale Stapelgröße beachtet:
2022-08-16 01:05:44 +03:00
```lua
local stack = ItemStack("default:stone 99")
2022-08-16 14:34:53 +03:00
local reste = inv:add_item("main", stack)
if reste:get_count() > 0 then
print("Inventar ist voll! " ..
reste:get_count() .. " Items wurden nicht hinzugefügt")
2022-08-16 01:05:44 +03:00
end
```
2022-08-16 14:34:53 +03:00
### Items nehmen
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Um Items von einer Liste zu löschen:
2022-08-16 01:05:44 +03:00
```lua
2022-08-16 14:34:53 +03:00
local genommen = inv:remove_item("main", stack)
print("Nahm " .. genommen:get_count())
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
### Stacks manipulieren
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Sie können einzelne Stacks ändern, indem Sie sie zuerst erhalten:
2022-08-16 01:05:44 +03:00
```lua
2022-08-16 14:34:53 +03:00
local stack = inv:get_stack(listenname, 0)
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
Dann ändern Sie sie durch das Setzen von Eigenschaften oder durch die Verwendung von
Methoden, welche die `stack_size` respektieren:
2022-08-16 01:05:44 +03:00
```lua
2022-08-16 14:34:53 +03:00
local stack = ItemStack("default:stone 50")
local zum_hinzufuegen = ItemStack("default:stone 100")
local reste = stack:add_item(to_add)
local genommen = stack:take_item(19)
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
print("Konnte nicht" .. reste:get_count() .. " der items hinzufügen.")
-- ^ wird 51 seind
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
print("Habe " .. stack:get_count() .. " items")
-- ^ wird 80 sein
2022-08-16 01:05:44 +03:00
-- min(50+100, stack_max) - 19 = 80
2022-08-16 14:34:53 +03:00
-- wobei stack_max = 99
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
`add_item` fügt Items zu einem ItemStack hinzu und gibt alle zurück, die nicht hinzugefügt werden konnten.
`take_item` nimmt bis zu der Anzahl der Items, kann aber auch weniger nehmen, und gibt den genommenen Stack zurück.
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Legen Sie schließlich den ItemStack fest:
2022-08-16 01:05:44 +03:00
```lua
2022-08-16 14:34:53 +03:00
inv:set_stack(listenname, 0, stack)
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
## Abnutzung
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Werkzeuge können abgenutzt sein; die Abnutzung wird in einem Fortschrittsbalken angezeigt und führt zum Abbruch des Werkzeugs, wenn es vollständig abgenutzt ist.
Die Abnutzung ist eine Zahl bis 65535; je höher sie ist, desto mehr ist das Werkzeug abgenutzt.
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Die Abnutzung kann mit `add_wear()` , `get_wear()` und `set_wear(wear)` beeinflusst werden.
2022-08-16 01:05:44 +03:00
```lua
local stack = ItemStack("default:pick_mese")
2022-08-16 14:34:53 +03:00
local max_nutzungen = 10
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
-- Dies geschieht automatisch, wenn Sie ein Werkzeug verwenden, das Dinge abbaut
-- Sie erhöht die Abnutzung eines Gegenstandes um einen Einsatz.
stack:add_wear(65535 / (max_nutzungen - 1))
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
Beim abbauen eines Blockes kann die Abnutzung des Werkzeugs von dem Block abhängen
der gegraben wird. Daher variiert max_nutzungen je nachdem, was gegraben wird.
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
## Lua Tabellen
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
ItemStacks und Inventare können in und aus Tabellen konvertiert werden.
Dies ist nützlich für Kopier- und Bulk-Operationen.
2022-08-16 01:05:44 +03:00
```lua
2022-08-16 14:34:53 +03:00
-- Gesamtes Inventar
local daten = inv1:get_lists()
inv2:set_lists(daten)
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
-- Eine Liste
local listendaten = inv1:get_list("main")
inv2:set_list("main", listendaten)
2022-08-16 01:05:44 +03:00
```
2022-08-16 14:34:53 +03:00
Die Tabelle der Listen, die von `get_lists()` zurückgegeben wird, wird in dieser Form vorliegen:
2022-08-16 01:05:44 +03:00
```lua
{
2022-08-16 14:34:53 +03:00
liste_eins = {
2022-08-16 01:05:44 +03:00
ItemStack,
ItemStack,
ItemStack,
ItemStack,
2022-08-16 14:34:53 +03:00
-- inv:get_size("liste_eins") Elemente
2022-08-16 01:05:44 +03:00
},
2022-08-16 14:34:53 +03:00
liste_zwei = {
2022-08-16 01:05:44 +03:00
ItemStack,
ItemStack,
ItemStack,
ItemStack,
2022-08-16 14:34:53 +03:00
-- inv:get_size("liste_zwei") Elemente
2022-08-16 01:05:44 +03:00
}
}
```
2022-08-16 14:34:53 +03:00
`get_list()` gibt eine einzelne Liste zurück, die lediglich eine Liste von ItemStacks ist.
2022-08-16 01:05:44 +03:00
2022-08-16 14:34:53 +03:00
Ein wichtiger Punkt ist, dass die obigen Set-Methoden die Größe der Listen nicht verändern.
Das bedeutet, dass Sie eine Liste löschen können, indem Sie sie auf eine leere Tabelle setzen, und sie wird nicht
verkleinert:
2022-08-16 01:05:44 +03:00
```lua
inv:set_list("main", {})
```