From 56e157adc72c036b4dc33f559daf9be534e12db8 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 5 Aug 2022 16:12:27 +0100 Subject: [PATCH] Callbacks: Fix code errors --- _en/items/callbacks.md | 4 +- _it/items/callbacks.md | 206 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 _it/items/callbacks.md diff --git a/_en/items/callbacks.md b/_en/items/callbacks.md index 9028baa..16affa8 100644 --- a/_en/items/callbacks.md +++ b/_en/items/callbacks.md @@ -160,7 +160,7 @@ nodes; it's common for mobs and mods to place nodes. To account for this, ```lua minetest.register_node("mymod:mynode", { - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing), + 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 @@ -193,7 +193,7 @@ out the tool, remove the node, and run the `after_dig_node` callback. ```lua minetest.register_node("mymod:mynode", { on_punch = function(pos, node, puncher, pointed_thing) - if clicker:is_player() then + if puncher:is_player() then minetest.chat_send_player(clicker:get_player_name(), "Ow!") end end, diff --git a/_it/items/callbacks.md b/_it/items/callbacks.md new file mode 100644 index 0000000..16affa8 --- /dev/null +++ b/_it/items/callbacks.md @@ -0,0 +1,206 @@ +--- +title: Node and Item Callbacks +layout: default +root: ../.. +idx: 2.15 +description: Learn about callbacks, actions, and events, including on_use, on_punch, on_place, on_rightclick +--- + +## Introduction + +Minetest heavily uses a callback-based modding design. A callback is a function +that you give to an API and is called when an event happens. For example, you +can provide an `on_punch` function in a node definition to be called when a player +punches a node. There are also global callbacks like +`minetest.register_on_punchnode` to receive events for all nodes. + +- [Item Callbacks](#item-callbacks) + - [on_use](#on_use) + - [on_place and on_secondary_use](#on_place-and-on_secondary_use) + - [on_drop](#on_drop) + - [after_use](#after_use) +- [item_place vs place_item](#item_place-vs-place_item) +- [Node Callbacks](#node-callbacks) + - [Right-clicking and placing a node](#right-clicking-and-placing-a-node) + - [Punching and digging](#punching-and-digging) + - [...and more!](#and-more) + + +## Item Callbacks + +When a player has a node, craftitem, or tool in their inventory, they may trigger +certain events: + +| Callback | Default binding | Default value | +|------------------|---------------------------|----------------------------------------------| +| on_use | left-click | nil | +| on_place | right-click on a node | `minetest.item_place` | +| on_secondary_use | right-click not on a node | `minetest.item_secondary_use` (does nothing) | +| on_drop | Q | `minetest.item_drop` | +| after_use | digging a node | nil | + + +### on_use + +Having a use callback prevents the item from being used to dig nodes. One common +use of the use callback is for food: + +```lua +minetest.register_craftitem("mymod:mudpie", { + description = "Alien Mud Pie", + inventory_image = "myfood_mudpie.png", + on_use = minetest.item_eat(20), +}) +``` + +The number supplied to the minetest.item_eat function is the number of hit +points healed when this food is consumed. Each heart icon the player has is +worth two hitpoints. A player can usually have up to 10 hearts, which is equal +to 20 hitpoints. + +minetest.item_eat() is a function that returns a function, setting it as the +on_use callback. This means the code above is equivalent to this: + +```lua +minetest.register_craftitem("mymod:mudpie", { + description = "Alien Mud Pie", + inventory_image = "myfood_mudpie.png", + on_use = function(...) + return minetest.do_item_eat(20, nil, ...) + end, +}) +``` + +By understanding how item_eat works by simply returning a function, it's +possible to modify it to do more complex behaviour like playing a custom sound. + + +### on_place and on_secondary_use + +The difference between `on_place` and `on_secondary_use` is that `on_place` is +called when the player is pointing at a node and `on_secondary_use` when the +player isn't. + +Both callbacks are called for all types of items. `on_place` defaults to the +`minetest.item_place` function, which handles calling the `on_rightclick` +callback of the pointed node or placing the wielded item if it is a node. + + +### on_drop + +on_drop is called when the player requests to drop an item, for example using +the drop key (Q) or dragging it outside of the inventory. It defaults to the +`minetest.item_drop` function, which will handle dropping the item. + + +### 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: + +```lua +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: + +```lua +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. + +```lua +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. + + +```lua +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.