minetest_modding_book/_de/items/callbacks.md
2022-08-15 00:20:20 +02:00

8.1 KiB

title layout root idx description
Block und Item Callbacks default ../.. 2.15 Learn about callbacks, actions, and events, including on_use, on_punch, on_place, on_rightclick

Einleitung

Minetest verwendet hauptsächlich ein Callback-basiertes Modding-Design. Ein Rückruf ist eine Funktion die Sie an eine API übergeben und die aufgerufen wird, wenn ein Ereignis eintritt. Zum Beispiel können Sie eine Funktion "on_punch" in einer Node-Definition angeben, die aufgerufen wird, wenn ein Spieler einen Knoten anstößt. Es gibt auch globale Callbacks wie minetest.register_on_punchnode, um Ereignisse für alle Knoten zu empfangen.

Item Callbacks

Wenn ein Spieler einen Block, einen Handwerksgegenstand oder ein Werkzeug in seinem Inventar hat, kann er folgende Ereignisse auslösen bestimmte Ereignisse:

Callback Standard-Bindung Standard Wert
on_use links-click nil
on_place rechts-click auf einen Block minetest.item_place
on_secondary_use rechts-click auf keinen Block minetest.item_secondary_use (does nothing)
on_drop Q minetest.item_drop
after_use Abbauen eines Blockes nil

on_use

Mit einem Verwendungsrückruf wird verhindert, dass das Item zum abbauen von Blöcken verwendet wird. Eine häufige Verwendung des Verwendungsrückrufs ist für Lebensmittel:

minetest.register_craftitem("meinemod:matschekuchen", {
    description = "Alien Matschekuchen",
    inventory_image = "meinessen_matschekuchen.png",
    on_use = minetest.item_eat(20),
})

Die Zahl, die an die Funktion minetest.item_eat übergeben wird, ist die Anzahl der Hitpoints, Punkte, die durch den Verzehr dieser Nahrung geheilt werden. Jedes Herzsymbol, das der Spieler hat, ist zwei Hitpoints wert. Ein Spieler kann in der Regel bis zu 10 Herzen haben, was gleichbedeutend ist mit 20 Hitpoints.

minetest.item_eat() ist eine Funktion, die eine Funktion zurückgibt und diese als on_use-Rückruf. Das bedeutet, dass der obige Code dem hier entspricht:

minetest.register_craftitem("meinemod:matschekuchen", {
    description = "Alien Matschekuchen",
    inventory_image = "meinessen_matschekuchen.png",
    on_use = function(...)
        return minetest.do_item_eat(20, nil, ...)
    end,
})

Wenn man versteht, wie item_eat funktioniert, indem es einfach eine Funktion zurückgibt, ist es möglich, die Funktion so zu ändern, dass sie ein komplexeres Verhalten wie das Abspielen eines benutzerdefinierten Sounds ermöglicht.

on_place und on_secondary_use

Der Unterschied zwischen on_place und on_secondary_use ist, dass on_place aufgerufen wird, wenn der Spieler auf einen Knoten zeigt und on_secondary_use, wenn der Spieler dies nicht tut.

Beide Callbacks werden für alle Arten von Items aufgerufen. on_place ist standardmäßig auf die Funktion minetest.item_place, die den Aufruf des on_rightclick Callback des angezeigten Knotens aufruft oder den geschwungenen Gegenstand platziert, wenn es ein Knoten ist.

Übersetzt mit www.DeepL.com/Translator (kostenlose Version)

on_drop

on_drop wird aufgerufen, wenn der Spieler einen Gegenstand fallen lassen will, zum Beispiel mit die Abwurftaste (Q) oder durch Ziehen außerhalb des Inventars. Es wird standardmäßig die Funktion minetest.item_drop, die das Fallenlassen des Gegenstandes übernimmt.

after_use

after_use is called when digging a node and allows you to customise how wear is applied to a tool. If after_use doesn't exist, then it is the same as:

after_use = function(itemstack, user, node, digparams)
    itemstack:add_wear(digparams.wear)
    return itemstack
end

item_place vs place_item

Minetest's API includes many different built-in callback implementations for you to use. These callbacks are named with the item type first, for example, minetest.item_place and minetest.node_dig. Some callback implementations are used directly whereas some are functions that return the callback:

minetest.register_item("mymod:example", {
    on_place = minetest.item_place,
    on_use = minetest.item_eat(10),
})

Minetest's API also includes built-in functions that do something. These are often named in a confusingly similar way to built-in callback implementations but have the verb first. Examples include minetest.place_item and minetest.dig_node - these functions allow you to dig and place nodes with a similar effect to players.

Node Callbacks

When a node is in an inventory, it uses Item Callbacks, as discussed above. When a node is placed in the world, it uses Node Callbacks. There are quite a lot of node callbacks, too many to discuss in this book. However, quite a few of them will be talked about later in the book.

Several of the callbacks are related to node operations such as placing and removing from the world. It's important to note that node operation callbacks like these aren't called from bulk changes - those that set a large number of nodes at once - for performance reasons. Therefore, you can't rely on these callbacks to always be called.

Right-clicking and placing a node

When the user right-clicks with an item whilst pointing at a node, the item's on_place callback is called. By default, this is set to minetest.item_place. If the pointed node has an on_rightclick callback and sneak (shift) is held, then the on_rightclick callback is called. Otherwise, minetest.item_place will place the node.

Placing a node will call both on_construct and after_place_node. on_construct is called by any node set event that wasn't in bulk and is just given the node's position and value .after_place_node is only called by node place, and so has more information - such as the placer and itemstack.

It's important to note that players aren't the only objects that can place nodes; it's common for mobs and mods to place nodes. To account for this, placer could be a player, entity, or nil.

minetest.register_node("mymod:mynode", {
    on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
        if clicker:is_player() then
            minetest.chat_send_player(clicker:get_player_name(), "Hello world!")
        end
    end,
    on_construct = function(pos, node)
        local meta = minetest.get_meta(pos)
        meta:set_string("infotext", "My node!")
    end,
    after_place_node = function(pos, placer, itemstack, pointed_thing)
        -- Make sure to check placer
        if placer and placer:is_player() then
            local meta = minetest.get_meta(pos)
            meta:set_string("owner", placer:get_player_name())
        end
    end,
})

Punching and digging

Punching is when the player left-clicks for a short period. If the wielded item has an on_use callback, this will be called. Otherwise, the on_punch callback on the pointed node will be called.

When the player attempts to dig a node, the on_dig callback on the node will be called. This defaults to minetest.node_dig, which will check for area protection, wear out the tool, remove the node, and run the after_dig_node callback.

minetest.register_node("mymod:mynode", {
    on_punch = function(pos, node, puncher, pointed_thing)
        if puncher:is_player() then
            minetest.chat_send_player(clicker:get_player_name(), "Ow!")
        end
    end,
})

...and more!

Check out Minetest's Lua API reference for a list of all node callbacks, and more information on the callbacks above.