Recommend core. instead of minetest.
This commit is contained in:
parent
05307506a6
commit
e896108377
@ -130,7 +130,7 @@ programs such as [Geogebra](https://www.geogebra.org).
|
||||
The following code registers a simple biome named grasslands biome:
|
||||
|
||||
```lua
|
||||
minetest.register_biome({
|
||||
core.register_biome({
|
||||
name = "grasslands",
|
||||
node_top = "default:dirt_with_grass",
|
||||
depth_top = 1,
|
||||
@ -174,7 +174,7 @@ details for where it can be placed, and how frequently it occurs.
|
||||
For example:
|
||||
|
||||
```lua
|
||||
minetest.register_decoration({
|
||||
core.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = {"base:dirt_with_grass"},
|
||||
sidelen = 16,
|
||||
@ -199,7 +199,7 @@ Schematic decorations are very similar to simple decoration, but involve the pla
|
||||
of a schematic instead of the placement of a single node. For example:
|
||||
|
||||
```lua
|
||||
minetest.register_decoration({
|
||||
core.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = {"base:desert_sand"},
|
||||
sidelen = 16,
|
||||
@ -207,7 +207,7 @@ minetest.register_decoration({
|
||||
biomes = {"desert"},
|
||||
y_max = 200,
|
||||
y_min = 1,
|
||||
schematic = minetest.get_modpath("plants") .. "/schematics/cactus.mts",
|
||||
schematic = core.get_modpath("plants") .. "/schematics/cactus.mts",
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
@ -229,7 +229,7 @@ to consider registering mapgen aliases of your own if you are making your own ga
|
||||
Mapgen aliases provide information to the core mapgen, and can be registered in the form:
|
||||
|
||||
```lua
|
||||
minetest.register_alias("mapgen_stone", "base:smoke_stone")
|
||||
core.register_alias("mapgen_stone", "base:smoke_stone")
|
||||
```
|
||||
|
||||
At a minimum you should register:
|
||||
|
@ -10,8 +10,8 @@ redirect_from:
|
||||
mapgen_object:
|
||||
level: warning
|
||||
title: LVMs and Mapgen
|
||||
message: Don't use `minetest.get_voxel_manip()` with mapgen, as it can cause glitches.
|
||||
Use `minetest.get_mapgen_object("voxelmanip")` instead.
|
||||
message: Don't use `core.get_voxel_manip()` with mapgen, as it can cause glitches.
|
||||
Use `core.get_mapgen_object("voxelmanip")` instead.
|
||||
---
|
||||
|
||||
## Introduction <!-- omit in toc -->
|
||||
@ -45,7 +45,7 @@ and maximum positions that you need to modify. Then you can create and read into
|
||||
an LVM. For example:
|
||||
|
||||
```lua
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local vm = core.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
```
|
||||
|
||||
@ -93,7 +93,7 @@ You can find out the content ID for a particular type of node with
|
||||
`get_content_id()`. For example:
|
||||
|
||||
```lua
|
||||
local c_stone = minetest.get_content_id("default:stone")
|
||||
local c_stone = core.get_content_id("default:stone")
|
||||
```
|
||||
|
||||
You can then check whether the node is stone:
|
||||
@ -164,17 +164,17 @@ For setting lighting and param2 data, use the appropriately named
|
||||
|
||||
`write_to_map()` takes a Boolean which is true if you want lighting to be
|
||||
calculated. If you pass false, you need to recalculate lighting at a future
|
||||
time using `minetest.fix_light`.
|
||||
time using `core.fix_light`.
|
||||
|
||||
## Example
|
||||
|
||||
```lua
|
||||
local function grass_to_dirt(pos1, pos2)
|
||||
local c_dirt = minetest.get_content_id("default:dirt")
|
||||
local c_grass = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_dirt = core.get_content_id("default:dirt")
|
||||
local c_grass = core.get_content_id("default:dirt_with_grass")
|
||||
|
||||
-- Read data into LVM
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local vm = core.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
local a = VoxelArea:new{
|
||||
MinEdge = emin,
|
||||
|
@ -122,13 +122,13 @@ Create an init.lua file with the following content:
|
||||
```lua
|
||||
print("This file will be run at load time!")
|
||||
|
||||
minetest.register_node("mymod:node", {
|
||||
core.register_node("mymod:node", {
|
||||
description = "This is a node",
|
||||
tiles = {"mymod_node.png"},
|
||||
groups = {cracky = 1}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mymod:node 3",
|
||||
recipe = { "default:dirt", "default:stone" },
|
||||
|
@ -177,7 +177,7 @@ nicer way to write it.
|
||||
The recommended way to include other Lua scripts in a mod is to use *dofile*.
|
||||
|
||||
```lua
|
||||
dofile(minetest.get_modpath("modname") .. "/script.lua")
|
||||
dofile(core.get_modpath("modname") .. "/script.lua")
|
||||
```
|
||||
|
||||
A script can return a value, which is useful for sharing private locals:
|
||||
@ -189,7 +189,7 @@ module.message = "Hello World!"
|
||||
return module
|
||||
|
||||
-- init.lua
|
||||
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
|
||||
local ret = dofile(core.get_modpath("modname") .. "/script.lua")
|
||||
print(ret.message) -- Hello world!
|
||||
```
|
||||
|
||||
|
@ -12,7 +12,7 @@ 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.
|
||||
`core.register_on_punchnode` to receive events for all nodes.
|
||||
|
||||
- [Item Callbacks](#item-callbacks)
|
||||
- [on_use](#on_use)
|
||||
@ -34,9 +34,9 @@ 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` |
|
||||
| on_place | right-click on a node | `core.item_place` |
|
||||
| on_secondary_use | right-click not on a node | `core.item_secondary_use` (does nothing) |
|
||||
| on_drop | Q | `core.item_drop` |
|
||||
| after_use | digging a node | nil |
|
||||
|
||||
|
||||
@ -46,27 +46,27 @@ 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", {
|
||||
core.register_craftitem("mymod:mudpie", {
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = minetest.item_eat(20),
|
||||
on_use = core.item_eat(20),
|
||||
})
|
||||
```
|
||||
|
||||
The number supplied to the minetest.item_eat function is the number of hit
|
||||
The number supplied to the core.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
|
||||
core.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", {
|
||||
core.register_craftitem("mymod:mudpie", {
|
||||
description = "Alien Mud Pie",
|
||||
inventory_image = "myfood_mudpie.png",
|
||||
on_use = function(...)
|
||||
return minetest.do_item_eat(20, nil, ...)
|
||||
return core.do_item_eat(20, nil, ...)
|
||||
end,
|
||||
})
|
||||
```
|
||||
@ -82,7 +82,7 @@ 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`
|
||||
`core.item_place` function, which handles calling the `on_rightclick`
|
||||
callback of the pointed node or placing the wielded item if it is a node.
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ callback of the pointed node or placing the wielded item if it is a node.
|
||||
|
||||
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.
|
||||
`core.item_drop` function, which will handle dropping the item.
|
||||
|
||||
|
||||
### after_use
|
||||
@ -110,20 +110,20 @@ end
|
||||
|
||||
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
|
||||
`core.item_place` and `core.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),
|
||||
core.register_item("mymod:example", {
|
||||
on_place = core.item_place,
|
||||
on_use = core.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
|
||||
but have the verb first. Examples include `core.place_item` and
|
||||
`core.dig_node` - these functions allow you to dig and place nodes with a
|
||||
similar effect to players.
|
||||
|
||||
|
||||
@ -144,9 +144,9 @@ 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`.
|
||||
`on_place` callback is called. By default, this is set to `core.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`
|
||||
then the `on_rightclick` callback is called. Otherwise, `core.item_place`
|
||||
will place the node.
|
||||
|
||||
Placing a node will call both `on_construct` and `after_place_node`.
|
||||
@ -159,20 +159,20 @@ 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", {
|
||||
core.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!")
|
||||
core.chat_send_player(clicker:get_player_name(), "Hello world!")
|
||||
end
|
||||
end,
|
||||
on_construct = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = core.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)
|
||||
local meta = core.get_meta(pos)
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
end
|
||||
end,
|
||||
@ -186,15 +186,15 @@ 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
|
||||
This defaults to `core.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", {
|
||||
core.register_node("mymod:mynode", {
|
||||
on_punch = function(pos, node, puncher, pointed_thing)
|
||||
if puncher:is_player() then
|
||||
minetest.chat_send_player(puncher:get_player_name(), "Ow!")
|
||||
core.chat_send_player(puncher:get_player_name(), "Ow!")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -106,7 +106,7 @@ chest. The node must be loaded because it is stored in
|
||||
|
||||
```lua
|
||||
on_punch = function(pos, node)
|
||||
local inv = minetest.get_inventory({ type="node", pos=pos })
|
||||
local inv = core.get_inventory({ type="node", pos=pos })
|
||||
-- now use the inventory
|
||||
end,
|
||||
```
|
||||
@ -128,7 +128,7 @@ Player inventories can be obtained similarly or using a player reference.
|
||||
The player must be online to access their inventory.
|
||||
|
||||
```lua
|
||||
local inv = minetest.get_inventory({ type="player", name="player1" })
|
||||
local inv = core.get_inventory({ type="player", name="player1" })
|
||||
-- or
|
||||
local inv = player:get_inventory()
|
||||
```
|
||||
@ -139,7 +139,7 @@ A detached inventory is one that is independent of players or nodes. Detached
|
||||
inventories also don't save over a restart.
|
||||
|
||||
```lua
|
||||
local inv = minetest.get_inventory({
|
||||
local inv = core.get_inventory({
|
||||
type="detached", name="inventory_name" })
|
||||
```
|
||||
|
||||
@ -147,7 +147,7 @@ Unlike the other types of inventory, you must first create a detached inventory
|
||||
before accessing it:
|
||||
|
||||
```lua
|
||||
minetest.create_detached_inventory("inventory_name")
|
||||
core.create_detached_inventory("inventory_name")
|
||||
```
|
||||
|
||||
The `create_detached_inventory` function accepts 3 arguments, where only the
|
||||
@ -156,7 +156,7 @@ callbacks, which can be used to control how players interact with the inventory:
|
||||
|
||||
```lua
|
||||
-- Input only detached inventory
|
||||
minetest.create_detached_inventory("inventory_name", {
|
||||
core.create_detached_inventory("inventory_name", {
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return count -- allow moving
|
||||
end,
|
||||
@ -170,9 +170,9 @@ minetest.create_detached_inventory("inventory_name", {
|
||||
end,
|
||||
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
minetest.chat_send_all(player:get_player_name() ..
|
||||
core.chat_send_all(player:get_player_name() ..
|
||||
" gave " .. stack:to_string() ..
|
||||
" to the donation chest from " .. minetest.pos_to_string(player:get_pos()))
|
||||
" to the donation chest from " .. core.pos_to_string(player:get_pos()))
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
@ -19,7 +19,7 @@ In the previous chapter, the concept of nodes and items was introduced, but a
|
||||
full definition of a node wasn't given. The Minetest world is a 3D grid of
|
||||
positions. Each position is called a node, and consists of the node type
|
||||
(name) and two parameters (param1 and param2). The function
|
||||
`minetest.register_node` is a bit misleading in that it doesn't actually
|
||||
`core.register_node` is a bit misleading in that it doesn't actually
|
||||
register a node - it registers a new *type* of node.
|
||||
|
||||
The node params are used to control how a node is individually rendered.
|
||||
@ -60,13 +60,13 @@ leaf nodes. You can use the allfaces_optional drawtype to allow users to opt-out
|
||||
of the slower drawing, in which case it'll act like a normal node.
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:diamond", {
|
||||
core.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {"mymod_diamond.png"},
|
||||
groups = {cracky = 3},
|
||||
})
|
||||
|
||||
minetest.register_node("default:leaves", {
|
||||
core.register_node("default:leaves", {
|
||||
description = "Leaves",
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"default_leaves.png"}
|
||||
@ -92,7 +92,7 @@ drawtype would result in the ability to see through the world.
|
||||
</figure>
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:obsidian_glass", {
|
||||
core.register_node("default:obsidian_glass", {
|
||||
description = "Obsidian Glass",
|
||||
drawtype = "glasslike",
|
||||
tiles = {"default_obsidian_glass.png"},
|
||||
@ -120,11 +120,11 @@ You can use the glasslike_framed_optional drawtype to allow the user to *opt-in*
|
||||
to the framed appearance.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:glass", {
|
||||
core.register_node("default:glass", {
|
||||
description = "Glass",
|
||||
drawtype = "glasslike_framed",
|
||||
tiles = {"default_glass.png", "default_glass_detail.png"},
|
||||
inventory_image = minetest.inventorycube("default_glass.png"),
|
||||
inventory_image = core.inventorycube("default_glass.png"),
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true, -- Sunlight can shine through block
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
@ -138,7 +138,7 @@ minetest.register_node("default:glass", {
|
||||
These nodes are not rendered and thus have no textures.
|
||||
|
||||
```lua
|
||||
minetest.register_node("myair:air", {
|
||||
core.register_node("myair:air", {
|
||||
description = "MyAir (you hacker you!)",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
@ -192,11 +192,11 @@ another for flowing liquid.
|
||||
```lua
|
||||
-- Some properties have been removed as they are beyond
|
||||
-- the scope of this chapter.
|
||||
minetest.register_node("default:water_source", {
|
||||
core.register_node("default:water_source", {
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
|
||||
inventory_image = minetest.inventorycube("default_water.png"),
|
||||
inventory_image = core.inventorycube("default_water.png"),
|
||||
-- ^ this is required to stop the inventory image from being animated
|
||||
|
||||
tiles = {
|
||||
@ -271,7 +271,7 @@ Node boxes allow you to create a node which is not cubic, but is instead made ou
|
||||
of as many cuboids as you like.
|
||||
|
||||
```lua
|
||||
minetest.register_node("stairs:stair_stone", {
|
||||
core.register_node("stairs:stair_stone", {
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
@ -305,7 +305,7 @@ create node boxes by dragging the edges, it is more visual than doing it by hand
|
||||
Sometimes you want different nodeboxes for when it is placed on the floor, wall, or ceiling like with torches.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:sign_wall", {
|
||||
core.register_node("default:sign_wall", {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "wallmounted",
|
||||
@ -341,7 +341,7 @@ invisible but still rendered.
|
||||
You can register a mesh node as so:
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:meshy", {
|
||||
core.register_node("mymod:meshy", {
|
||||
drawtype = "mesh",
|
||||
|
||||
-- Holds the texture for each "material"
|
||||
@ -370,7 +370,7 @@ instead use the `nodebox` drawtype to provide a 3D effect. The `signlike` drawty
|
||||
is, however, commonly used by ladders.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:ladder_wood", {
|
||||
core.register_node("default:ladder_wood", {
|
||||
drawtype = "signlike",
|
||||
|
||||
tiles = {"default_ladder_wood.png"},
|
||||
@ -397,7 +397,7 @@ minetest.register_node("default:ladder_wood", {
|
||||
Plantlike nodes draw their tiles in an X like pattern.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:papyrus", {
|
||||
core.register_node("default:papyrus", {
|
||||
drawtype = "plantlike",
|
||||
|
||||
-- Only one texture used
|
||||
@ -423,7 +423,7 @@ and ceilings.
|
||||
</figure>
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:clingere", {
|
||||
core.register_node("mymod:clingere", {
|
||||
drawtype = "firelike",
|
||||
|
||||
-- Only one texture used
|
||||
|
@ -48,7 +48,7 @@ Item definitions consist of an *item name* and a *definition table*.
|
||||
The definition table contains attributes that affect the behaviour of the item.
|
||||
|
||||
```lua
|
||||
minetest.register_craftitem("modname:itemname", {
|
||||
core.register_craftitem("modname:itemname", {
|
||||
description = "My Special Item",
|
||||
inventory_image = "modname_itemname.png"
|
||||
})
|
||||
@ -83,7 +83,7 @@ Registering an alias is pretty simple. A good way to remember the order of the
|
||||
arguments is `from → to` where *from* is the alias and *to* is the target.
|
||||
|
||||
```lua
|
||||
minetest.register_alias("dirt", "default:dirt")
|
||||
core.register_alias("dirt", "default:dirt")
|
||||
```
|
||||
|
||||
Mods need to make sure to resolve aliases before dealing directly with item names,
|
||||
@ -91,7 +91,7 @@ as the engine won't do this.
|
||||
This is pretty simple though:
|
||||
|
||||
```lua
|
||||
itemname = minetest.registered_aliases[itemname] or itemname
|
||||
itemname = core.registered_aliases[itemname] or itemname
|
||||
```
|
||||
|
||||
### Textures
|
||||
@ -113,7 +113,7 @@ Registering nodes is similar to registering items, just with a different
|
||||
function:
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:diamond", {
|
||||
core.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {"mymod_diamond.png"},
|
||||
is_ground_content = true,
|
||||
@ -135,7 +135,7 @@ Remember that +Y is upwards in Minetest, as is the convention with
|
||||
most 3D computer games.
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:diamond", {
|
||||
core.register_node("mymod:diamond", {
|
||||
description = "Alien Diamond",
|
||||
tiles = {
|
||||
"mymod_diamond_up.png", -- y+
|
||||
@ -178,7 +178,7 @@ pattern to work. In the example below, the fragments need to be in a
|
||||
chair-like pattern for the craft to work.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shaped",
|
||||
output = "mymod:diamond_chair 99",
|
||||
recipe = {
|
||||
@ -196,7 +196,7 @@ If this empty column shouldn't be required, then the empty strings can be left
|
||||
out like so:
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
output = "mymod:diamond_chair 99",
|
||||
recipe = {
|
||||
{"mymod:diamond_fragments", "" },
|
||||
@ -215,7 +215,7 @@ Shapeless recipes are a type of recipe which is used when it doesn't matter
|
||||
where the ingredients are placed, just that they're there.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mymod:diamond 3",
|
||||
recipe = {
|
||||
@ -232,7 +232,7 @@ Recipes with the type "cooking" are not made in the crafting grid,
|
||||
but are cooked in furnaces, or other cooking tools that might be found in mods.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "cooking",
|
||||
output = "mymod:diamond_fragments",
|
||||
recipe = "default:coalblock",
|
||||
@ -254,7 +254,7 @@ This type is an accompaniment to the cooking type, as it defines
|
||||
what can be burned in furnaces and other cooking tools from mods.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "mymod:diamond",
|
||||
burntime = 300,
|
||||
@ -281,7 +281,7 @@ Secondly, groups can be used in a craft recipe instead of an item name to allow
|
||||
any item in the group to be used.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "mymod:diamond_thing 3",
|
||||
recipe = {"group:wood", "mymod:diamond"}
|
||||
@ -322,7 +322,7 @@ If the item a player is currently wielding doesn't have an explicit tool
|
||||
capability, then the capability of the current hand is used instead.
|
||||
|
||||
```lua
|
||||
minetest.register_tool("mymod:tool", {
|
||||
core.register_tool("mymod:tool", {
|
||||
description = "My Tool",
|
||||
inventory_image = "mymod_tool.png",
|
||||
tool_capabilities = {
|
||||
|
@ -48,7 +48,7 @@ loaded from the world database outside of the generation limit.
|
||||
You can read from the map once you have a position:
|
||||
|
||||
```lua
|
||||
local node = minetest.get_node({ x = 1, y = 3, z = 4 })
|
||||
local node = core.get_node({ x = 1, y = 3, z = 4 })
|
||||
print(dump(node)) --> { name=.., param1=.., param2=.. }
|
||||
```
|
||||
|
||||
@ -62,7 +62,7 @@ The function will always return a table containing the node information:
|
||||
It's worth noting that the function won't load the containing block if the block
|
||||
is inactive, but will instead return a table with `name` being `ignore`.
|
||||
|
||||
You can use `minetest.get_node_or_nil` instead, which will return `nil` rather
|
||||
You can use `core.get_node_or_nil` instead, which will return `nil` rather
|
||||
than a table with a name of `ignore`. It still won't load the block, however.
|
||||
This may still return `ignore` if a block actually contains ignore.
|
||||
This will happen near the edge of the map as defined by the map generation
|
||||
@ -77,15 +77,15 @@ For example, say we wanted to make a certain type of plant that grows
|
||||
better near mese; you would need to search for any nearby mese nodes,
|
||||
and adapt the growth rate accordingly.
|
||||
|
||||
`minetest.find_node_near` will return the first found node in a certain radius
|
||||
`core.find_node_near` will return the first found node in a certain radius
|
||||
which matches the node names or groups given. In the following example,
|
||||
we look for a mese node within 5 nodes of the position:
|
||||
|
||||
```lua
|
||||
local grow_speed = 1
|
||||
local node_pos = minetest.find_node_near(pos, 5, { "default:mese" })
|
||||
local node_pos = core.find_node_near(pos, 5, { "default:mese" })
|
||||
if node_pos then
|
||||
minetest.chat_send_all("Node found at: " .. dump(node_pos))
|
||||
core.chat_send_all("Node found at: " .. dump(node_pos))
|
||||
grow_speed = 2
|
||||
end
|
||||
```
|
||||
@ -97,7 +97,7 @@ nearby. You should then use a function that can find multiple nodes in the area:
|
||||
local pos1 = vector.subtract(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos2 = vector.add(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos_list =
|
||||
minetest.find_nodes_in_area(pos1, pos2, { "default:mese" })
|
||||
core.find_nodes_in_area(pos1, pos2, { "default:mese" })
|
||||
local grow_speed = 1 + #pos_list
|
||||
```
|
||||
|
||||
@ -109,7 +109,7 @@ order to fix this, we will need to manually check the range ourselves:
|
||||
local pos1 = vector.subtract(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos2 = vector.add(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos_list =
|
||||
minetest.find_nodes_in_area(pos1, pos2, { "default:mese" })
|
||||
core.find_nodes_in_area(pos1, pos2, { "default:mese" })
|
||||
local grow_speed = 1
|
||||
for i=1, #pos_list do
|
||||
local delta = vector.subtract(pos_list[i], pos)
|
||||
@ -138,9 +138,9 @@ lighting to be recalculated and node callbacks to run, which means that set_node
|
||||
is fairly slow for large numbers of nodes.
|
||||
|
||||
```lua
|
||||
minetest.set_node({ x = 1, y = 3, z = 4 }, { name = "default:mese" })
|
||||
core.set_node({ x = 1, y = 3, z = 4 }, { name = "default:mese" })
|
||||
|
||||
local node = minetest.get_node({ x = 1, y = 3, z = 4 })
|
||||
local node = core.get_node({ x = 1, y = 3, z = 4 })
|
||||
print(node.name) --> default:mese
|
||||
```
|
||||
|
||||
@ -153,7 +153,7 @@ two.
|
||||
You can set a node without deleting metadata or the inventory like so:
|
||||
|
||||
```lua
|
||||
minetest.swap_node({ x = 1, y = 3, z = 4 }, { name = "default:mese" })
|
||||
core.swap_node({ x = 1, y = 3, z = 4 }, { name = "default:mese" })
|
||||
```
|
||||
|
||||
### Removing Nodes
|
||||
@ -163,15 +163,15 @@ A node must always be present. To remove a node, you set the position to `air`.
|
||||
The following two lines will both remove a node, and are both identical:
|
||||
|
||||
```lua
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(pos, { name = "air" })
|
||||
core.remove_node(pos)
|
||||
core.set_node(pos, { name = "air" })
|
||||
```
|
||||
|
||||
In fact, remove_node is just a helper function that calls set_node with `"air"`.
|
||||
|
||||
## Loading Blocks
|
||||
|
||||
You can use `minetest.emerge_area` to load map blocks. Emerge area is asynchronous,
|
||||
You can use `core.emerge_area` to load map blocks. Emerge area is asynchronous,
|
||||
meaning the blocks won't be loaded instantly. Instead, they will be loaded
|
||||
soon in the future, and the callback will be called each time.
|
||||
|
||||
@ -182,7 +182,7 @@ local pos1 = vector.subtract(pos, halfsize)
|
||||
local pos2 = vector.add (pos, halfsize)
|
||||
|
||||
local context = {} -- persist data between callback calls
|
||||
minetest.emerge_area(pos1, pos2, emerge_callback, context)
|
||||
core.emerge_area(pos1, pos2, emerge_callback, context)
|
||||
```
|
||||
|
||||
Minetest will call `emerge_callback` whenever it loads a block, with some
|
||||
@ -202,12 +202,12 @@ local function emerge_callback(pos, action,
|
||||
|
||||
-- Send progress message
|
||||
if context.total_blocks == context.loaded_blocks then
|
||||
minetest.chat_send_all("Finished loading blocks!")
|
||||
core.chat_send_all("Finished loading blocks!")
|
||||
else
|
||||
local perc = 100 * context.loaded_blocks / context.total_blocks
|
||||
local msg = string.format("Loading blocks %d/%d (%.2f%%)",
|
||||
context.loaded_blocks, context.total_blocks, perc)
|
||||
minetest.chat_send_all(msg)
|
||||
core.chat_send_all(msg)
|
||||
end
|
||||
end
|
||||
```
|
||||
@ -226,7 +226,7 @@ local halfsize = { x = 10, y = 10, z = 10 }
|
||||
local pos1 = vector.subtract(pos, halfsize)
|
||||
local pos2 = vector.add (pos, halfsize)
|
||||
|
||||
minetest.delete_area(pos1, pos2)
|
||||
core.delete_area(pos1, pos2)
|
||||
```
|
||||
|
||||
This will delete all map blocks in that area, *inclusive*. This means that some
|
||||
|
@ -48,7 +48,7 @@ which is referred to as a Lua entity, as discussed later.
|
||||
`get_pos` and `set_pos` exist to allow you to get and set an entity's position.
|
||||
|
||||
```lua
|
||||
local object = minetest.get_player_by_name("bob")
|
||||
local object = core.get_player_by_name("bob")
|
||||
local pos = object:get_pos()
|
||||
object:set_pos({ x = pos.x, y = pos.y + 1, z = pos.z })
|
||||
```
|
||||
@ -152,7 +152,7 @@ Both an ObjectRef and an entity table provide ways to get the counterpart:
|
||||
```lua
|
||||
local entity = object:get_luaentity()
|
||||
local object = entity.object
|
||||
print("entity is at " .. minetest.pos_to_string(object:get_pos()))
|
||||
print("entity is at " .. core.pos_to_string(object:get_pos()))
|
||||
```
|
||||
|
||||
There are a number of available callbacks for use with entities.
|
||||
@ -164,9 +164,9 @@ function MyEntity:on_step(dtime)
|
||||
local pos_down = vector.subtract(pos, vector.new(0, 1, 0))
|
||||
|
||||
local delta
|
||||
if minetest.get_node(pos_down).name == "air" then
|
||||
if core.get_node(pos_down).name == "air" then
|
||||
delta = vector.new(0, -1, 0)
|
||||
elseif minetest.get_node(pos).name == "air" then
|
||||
elseif core.get_node(pos).name == "air" then
|
||||
delta = vector.new(0, 0, 1)
|
||||
else
|
||||
delta = vector.new(0, 1, 0)
|
||||
@ -178,7 +178,7 @@ function MyEntity:on_step(dtime)
|
||||
end
|
||||
|
||||
function MyEntity:on_punch(hitter)
|
||||
minetest.chat_send_player(hitter:get_player_name(), self.message)
|
||||
core.chat_send_player(hitter:get_player_name(), self.message)
|
||||
end
|
||||
```
|
||||
|
||||
@ -192,14 +192,14 @@ needs to stored.
|
||||
|
||||
```lua
|
||||
function MyEntity:get_staticdata()
|
||||
return minetest.write_json({
|
||||
return core.write_json({
|
||||
message = self.message,
|
||||
})
|
||||
end
|
||||
|
||||
function MyEntity:on_activate(staticdata, dtime_s)
|
||||
if staticdata ~= "" and staticdata ~= nil then
|
||||
local data = minetest.parse_json(staticdata) or {}
|
||||
local data = core.parse_json(staticdata) or {}
|
||||
self:set_message(data.message)
|
||||
end
|
||||
end
|
||||
@ -217,14 +217,14 @@ This means that staticdata could be empty.
|
||||
Finally, you need to register the type table using the aptly named `register_entity`.
|
||||
|
||||
```lua
|
||||
minetest.register_entity("mymod:entity", MyEntity)
|
||||
core.register_entity("mymod:entity", MyEntity)
|
||||
```
|
||||
|
||||
The entity can be spawned by a mod like so:
|
||||
|
||||
```lua
|
||||
local pos = { x = 1, y = 2, z = 3 }
|
||||
local obj = minetest.add_entity(pos, "mymod:entity", nil)
|
||||
local obj = core.add_entity(pos, "mymod:entity", nil)
|
||||
```
|
||||
|
||||
The third parameter is the initial staticdata.
|
||||
|
@ -53,7 +53,7 @@ The data itself, such as a node's type or an stack's count, is not metadata.
|
||||
If you know the position of a node, you can retrieve its metadata:
|
||||
|
||||
```lua
|
||||
local meta = minetest.get_meta({ x = 1, y = 2, z = 3 })
|
||||
local meta = core.get_meta({ x = 1, y = 2, z = 3 })
|
||||
```
|
||||
|
||||
Player and ItemStack metadata are obtained using `get_meta()`:
|
||||
@ -99,7 +99,7 @@ This is useful when showing the ownership or status of a node.
|
||||
|
||||
`description` is used in ItemStack Metadata to override the description when
|
||||
hovering over the stack in an inventory.
|
||||
You can use colours by encoding them with `minetest.colorize()`.
|
||||
You can use colours by encoding them with `core.colorize()`.
|
||||
|
||||
`owner` is a common key used to store the username of the player that owns the
|
||||
item or node.
|
||||
@ -116,9 +116,9 @@ with another program.
|
||||
|
||||
```lua
|
||||
local data = { username = "player1", score = 1234 }
|
||||
meta:set_string("foo", minetest.serialize(data))
|
||||
meta:set_string("foo", core.serialize(data))
|
||||
|
||||
data = minetest.deserialize(meta:get_string("foo"))
|
||||
data = core.deserialize(meta:get_string("foo"))
|
||||
```
|
||||
|
||||
### Private Metadata
|
||||
@ -149,7 +149,7 @@ Mod storage is per-mod, and can only be obtained during load time in order to
|
||||
know which mod is requesting it.
|
||||
|
||||
```lua
|
||||
local storage = minetest.get_mod_storage()
|
||||
local storage = core.get_mod_storage()
|
||||
```
|
||||
|
||||
You can now manipulate the storage just like metadata:
|
||||
@ -169,10 +169,10 @@ it is used.
|
||||
local backend
|
||||
if use_database then
|
||||
backend =
|
||||
dofile(minetest.get_modpath("mymod") .. "/backend_sqlite.lua")
|
||||
dofile(core.get_modpath("mymod") .. "/backend_sqlite.lua")
|
||||
else
|
||||
backend =
|
||||
dofile(minetest.get_modpath("mymod") .. "/backend_storage.lua")
|
||||
dofile(core.get_modpath("mymod") .. "/backend_storage.lua")
|
||||
end
|
||||
|
||||
backend.get_foo("a")
|
||||
@ -182,15 +182,15 @@ backend.set_foo("a", { score = 3 })
|
||||
The backend_storage.lua file should include a mod storage implementation:
|
||||
|
||||
```lua
|
||||
local storage = minetest.get_mod_storage()
|
||||
local storage = core.get_mod_storage()
|
||||
local backend = {}
|
||||
|
||||
function backend.set_foo(key, value)
|
||||
storage:set_string(key, minetest.serialize(value))
|
||||
storage:set_string(key, core.serialize(value))
|
||||
end
|
||||
|
||||
function backend.get_foo(key)
|
||||
return minetest.deserialize(storage:get_string(key))
|
||||
return core.deserialize(storage:get_string(key))
|
||||
end
|
||||
|
||||
return backend
|
||||
@ -207,7 +207,7 @@ Insecure environments will be covered in more detail in the
|
||||
[Security](../quality/security.html) chapter.
|
||||
|
||||
```lua
|
||||
local ie = minetest.request_insecure_environment()
|
||||
local ie = core.request_insecure_environment()
|
||||
assert(ie, "Please add mymod to secure.trusted_mods in the settings")
|
||||
|
||||
local _sql = ie.require("lsqlite3")
|
||||
@ -244,4 +244,4 @@ They're well suited for large data sets.
|
||||
## Your Turn
|
||||
|
||||
* Make a node which disappears after it has been punched five times.
|
||||
(Use `on_punch` in the node definition and `minetest.set_node`.)
|
||||
(Use `on_punch` in the node definition and `core.set_node`.)
|
||||
|
@ -37,7 +37,7 @@ Node timers are directly tied to a single node.
|
||||
You can manage node timers by obtaining a NodeTimerRef object.
|
||||
|
||||
```lua
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
local timer = core.get_node_timer(pos)
|
||||
timer:start(10.5) -- in seconds
|
||||
```
|
||||
|
||||
@ -45,9 +45,9 @@ When a node timer is up, the `on_timer` method in the node's definition table wi
|
||||
be called. The method only takes a single parameter, the position of the node:
|
||||
|
||||
```lua
|
||||
minetest.register_node("autodoors:door_open", {
|
||||
core.register_node("autodoors:door_open", {
|
||||
on_timer = function(pos)
|
||||
minetest.set_node(pos, { name = "autodoors:door" })
|
||||
core.set_node(pos, { name = "autodoors:door" })
|
||||
return false
|
||||
end
|
||||
})
|
||||
@ -68,15 +68,15 @@ has a chance to appear near water.
|
||||
|
||||
|
||||
```lua
|
||||
minetest.register_node("aliens:grass", {
|
||||
core.register_node("aliens:grass", {
|
||||
description = "Alien Grass",
|
||||
light_source = 3, -- The node radiates light. Min 0, max 14
|
||||
tiles = {"aliens_grass.png"},
|
||||
groups = {choppy=1},
|
||||
on_use = minetest.item_eat(20)
|
||||
on_use = core.item_eat(20)
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
core.register_abm({
|
||||
nodenames = {"default:dirt_with_grass"},
|
||||
neighbors = {"default:water_source", "default:water_flowing"},
|
||||
interval = 10.0, -- Run every 10 seconds
|
||||
@ -84,7 +84,7 @@ minetest.register_abm({
|
||||
action = function(pos, node, active_object_count,
|
||||
active_object_count_wider)
|
||||
local pos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(pos, {name = "aliens:grass"})
|
||||
core.set_node(pos, {name = "aliens:grass"})
|
||||
end
|
||||
})
|
||||
```
|
||||
@ -93,7 +93,7 @@ This ABM runs every ten seconds, and for each matching node, there is
|
||||
a 1 in 50 chance of it running.
|
||||
If the ABM runs on a node, an alien grass node is placed above it.
|
||||
Please be warned, this will delete any node previously located in that position.
|
||||
To prevent this you should include a check using minetest.get_node to make sure there is space for the grass.
|
||||
To prevent this you should include a check using core.get_node to make sure there is space for the grass.
|
||||
|
||||
Specifying a neighbour is optional.
|
||||
If you specify multiple neighbours, only one of them needs to be
|
||||
|
@ -14,7 +14,7 @@ cmd_online:
|
||||
bridge allows players to run commands without joining the game.
|
||||
|
||||
So make sure that you don't assume that the player is online.
|
||||
You can check by seeing if `minetest.get_player_by_name` returns a player.
|
||||
You can check by seeing if `core.get_player_by_name` returns a player.
|
||||
|
||||
cb_cmdsprivs:
|
||||
level: warning
|
||||
@ -47,7 +47,7 @@ sending messages, intercepting messages, and registering chat commands.
|
||||
To send a message to every player in the game, call the `chat_send_all` function.
|
||||
|
||||
```lua
|
||||
minetest.chat_send_all("This is a chat message to all players")
|
||||
core.chat_send_all("This is a chat message to all players")
|
||||
```
|
||||
|
||||
Here is an example of how this appears in-game:
|
||||
@ -63,7 +63,7 @@ The message appears on a separate line to distinguish it from in-game player cha
|
||||
To send a message to a specific player, call the `chat_send_player` function:
|
||||
|
||||
```lua
|
||||
minetest.chat_send_player("player1", "This is a chat message for player1")
|
||||
core.chat_send_player("player1", "This is a chat message for player1")
|
||||
```
|
||||
|
||||
This message displays in the same manner as messages to all players, but is
|
||||
@ -74,7 +74,7 @@ only visible to the named player, in this case, player1.
|
||||
To register a chat command, for example `/foo`, use `register_chatcommand`:
|
||||
|
||||
```lua
|
||||
minetest.register_chatcommand("foo", {
|
||||
core.register_chatcommand("foo", {
|
||||
privs = {
|
||||
interact = true,
|
||||
},
|
||||
@ -166,7 +166,7 @@ or the [PIL documentation](https://www.lua.org/pil/20.2.html).
|
||||
To intercept a message, use register_on_chat_message:
|
||||
|
||||
```lua
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
core.register_on_chat_message(function(name, message)
|
||||
print(name .. " said " .. message)
|
||||
return false
|
||||
end)
|
||||
@ -182,10 +182,10 @@ You should make sure you take into account that it may be a chat command,
|
||||
or the user may not have `shout`.
|
||||
|
||||
```lua
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
core.register_on_chat_message(function(name, message)
|
||||
if message:sub(1, 1) == "/" then
|
||||
print(name .. " ran chat command")
|
||||
elseif minetest.check_player_privs(name, { shout = true }) then
|
||||
elseif core.check_player_privs(name, { shout = true }) then
|
||||
print(name .. " said " .. message)
|
||||
else
|
||||
print(name .. " tried to say " .. message ..
|
||||
|
@ -146,7 +146,7 @@ function guessing.get_formspec(name)
|
||||
local formspec = {
|
||||
"formspec_version[4]",
|
||||
"size[6,3.476]",
|
||||
"label[0.375,0.5;", minetest.formspec_escape(text), "]",
|
||||
"label[0.375,0.5;", core.formspec_escape(text), "]",
|
||||
"field[0.375,1.25;5.25,0.8;number;Number;]",
|
||||
"button[1.5,2.3;3,0.8;guess;Guess]"
|
||||
}
|
||||
@ -166,10 +166,10 @@ is using `show_formspec`:
|
||||
|
||||
```lua
|
||||
function guessing.show_to(name)
|
||||
minetest.show_formspec(name, "guessing:game", guessing.get_formspec(name))
|
||||
core.show_formspec(name, "guessing:game", guessing.get_formspec(name))
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("game", {
|
||||
core.register_chatcommand("game", {
|
||||
func = function(name)
|
||||
guessing.show_to(name)
|
||||
end,
|
||||
@ -206,19 +206,19 @@ The method for this is called formspec field submission, and for `show_formspec`
|
||||
submission is received using a global callback:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
core.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "guessing:game" then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.guess then
|
||||
local pname = player:get_player_name()
|
||||
minetest.chat_send_all(pname .. " guessed " .. fields.number)
|
||||
core.chat_send_all(pname .. " guessed " .. fields.number)
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
The function given in `minetest.register_on_player_receive_fields` is called
|
||||
The function given in `core.register_on_player_receive_fields` is called
|
||||
every time a user submits a form. Most callbacks will need to check the formname given
|
||||
to the function, and exit if it is not the right form; however, some callbacks
|
||||
may need to work on multiple forms, or on all forms.
|
||||
@ -239,7 +239,7 @@ the formspec based on guesses. The way to do this is using a concept called
|
||||
|
||||
### Contexts
|
||||
|
||||
In many cases you want minetest.show_formspec to give information
|
||||
In many cases you want core.show_formspec to give information
|
||||
to the callback which you don't want to send to the client. This might include
|
||||
what a chat command was called with, or what the dialog is about. In this case,
|
||||
the target value that needs to be remembered.
|
||||
@ -255,7 +255,7 @@ local function get_context(name)
|
||||
return context
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
core.register_on_leaveplayer(function(player)
|
||||
_contexts[player:get_player_name()] = nil
|
||||
end)
|
||||
```
|
||||
@ -269,7 +269,7 @@ function guessing.show_to(name)
|
||||
context.target = context.target or math.random(1, 10)
|
||||
|
||||
local fs = guessing.get_formspec(name, context)
|
||||
minetest.show_formspec(name, "guessing:game", fs)
|
||||
core.show_formspec(name, "guessing:game", fs)
|
||||
end
|
||||
```
|
||||
|
||||
@ -318,13 +318,13 @@ There are three different ways that a formspec can be delivered to the client:
|
||||
|
||||
### Node Meta Formspecs
|
||||
|
||||
`minetest.show_formspec` is not the only way to show a formspec; you can also
|
||||
`core.show_formspec` is not the only way to show a formspec; you can also
|
||||
add formspecs to a [node's metadata](../map/storage.html). For example,
|
||||
this is used with chests to allow for faster opening times -
|
||||
you don't need to wait for the server to send the player the chest formspec.
|
||||
|
||||
```lua
|
||||
minetest.register_node("mymod:rightclick", {
|
||||
core.register_node("mymod:rightclick", {
|
||||
description = "Rightclick me!",
|
||||
tiles = {"mymod_rightclick.png"},
|
||||
groups = {cracky = 1},
|
||||
@ -333,7 +333,7 @@ minetest.register_node("mymod:rightclick", {
|
||||
-- The following code sets the formspec for chest.
|
||||
-- Meta is a way of storing data onto a node.
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = core.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"formspec_version[4]" ..
|
||||
"size[5,5]" ..
|
||||
@ -355,7 +355,7 @@ receive form input for meta formspecs, you must include an
|
||||
`on_receive_fields` entry when registering the node.
|
||||
|
||||
This style of callback triggers when you press enter
|
||||
in a field, which is impossible with `minetest.show_formspec`;
|
||||
in a field, which is impossible with `core.show_formspec`;
|
||||
however, this kind of form can only be shown by right-clicking on a
|
||||
node. It cannot be triggered programmatically.
|
||||
|
||||
|
@ -89,7 +89,7 @@ to the right of the window, but to resize without breaking.
|
||||
You can create a HUD element once you have a copy of the player object:
|
||||
|
||||
```lua
|
||||
local player = minetest.get_player_by_name("username")
|
||||
local player = core.get_player_by_name("username")
|
||||
local idx = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = {x = 0.5, y = 0.5},
|
||||
@ -281,9 +281,9 @@ function score.update_hud(player)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(score.update_hud)
|
||||
core.register_on_joinplayer(score.update_hud)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
core.register_on_leaveplayer(function(player)
|
||||
saved_huds[player:get_player_name()] = nil
|
||||
end)
|
||||
```
|
||||
|
@ -28,9 +28,9 @@ Here is an example of how to add an antigravity command, which
|
||||
puts the caller in low G:
|
||||
|
||||
```lua
|
||||
minetest.register_chatcommand("antigravity", {
|
||||
core.register_chatcommand("antigravity", {
|
||||
func = function(name, param)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
local player = core.get_player_by_name(name)
|
||||
player:set_physics_override({
|
||||
gravity = 0.1, -- set gravity to 10% of its original value
|
||||
-- (0.1 * 9.81)
|
||||
|
@ -48,7 +48,7 @@ Privileges are **not** for indicating class or status.
|
||||
Use `register_privilege` to declare a new privilege:
|
||||
|
||||
```lua
|
||||
minetest.register_privilege("vote", {
|
||||
core.register_privilege("vote", {
|
||||
description = "Can vote on issues",
|
||||
give_to_singleplayer = true
|
||||
})
|
||||
@ -62,7 +62,7 @@ actually needed in the above definition.
|
||||
To quickly check whether a player has all the required privileges:
|
||||
|
||||
```lua
|
||||
local has, missing = minetest.check_player_privs(player_or_name, {
|
||||
local has, missing = core.check_player_privs(player_or_name, {
|
||||
interact = true,
|
||||
vote = true })
|
||||
```
|
||||
@ -72,7 +72,7 @@ If `has` is false, then `missing` will contain a key-value table
|
||||
of the missing privileges.
|
||||
|
||||
```lua
|
||||
local has, missing = minetest.check_player_privs(name, {
|
||||
local has, missing = core.check_player_privs(name, {
|
||||
interact = true,
|
||||
vote = true })
|
||||
|
||||
@ -87,7 +87,7 @@ If you don't need to check the missing privileges, you can put
|
||||
`check_player_privs` directly into the if statement.
|
||||
|
||||
```lua
|
||||
if not minetest.check_player_privs(name, { interact=true }) then
|
||||
if not core.check_player_privs(name, { interact=true }) then
|
||||
return false, "You need interact for this!"
|
||||
end
|
||||
```
|
||||
@ -99,11 +99,11 @@ being online.
|
||||
|
||||
|
||||
```lua
|
||||
local privs = minetest.get_player_privs(name)
|
||||
local privs = core.get_player_privs(name)
|
||||
print(dump(privs))
|
||||
|
||||
privs.vote = true
|
||||
minetest.set_player_privs(name, privs)
|
||||
core.set_player_privs(name, privs)
|
||||
```
|
||||
|
||||
Privileges are always specified as a key-value table with the key being
|
||||
|
@ -100,7 +100,7 @@ what is listening to something.
|
||||
|
||||
In the next chapter, we will discuss how to automatically test your
|
||||
code and one of the problems we will have is how to separate your logic
|
||||
(calculations, what should be done) from API calls (`minetest.*`, other mods)
|
||||
(calculations, what should be done) from API calls (`core.*`, other mods)
|
||||
as much as possible.
|
||||
|
||||
One way to do this is to think about:
|
||||
@ -173,14 +173,14 @@ function land.show_create_formspec(name)
|
||||
]]
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("/land", {
|
||||
core.register_chatcommand("/land", {
|
||||
privs = { land = true },
|
||||
func = function(name)
|
||||
land.handle_creation_request(name)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
land.handle_create_submit(player:get_player_name(),
|
||||
fields.area_name)
|
||||
@ -227,7 +227,7 @@ this isn't the real world. A good compromise is to reduce the mod into two
|
||||
parts:
|
||||
|
||||
* **API** - This was the model and controller above. There should be no uses of
|
||||
`minetest.` here.
|
||||
`core.` here.
|
||||
* **View** - This was also the view above. It's a good idea to structure this into separate
|
||||
files for each type of event.
|
||||
|
||||
|
@ -43,11 +43,11 @@ give themselves moderator privileges:
|
||||
|
||||
```lua
|
||||
local function show_formspec(name)
|
||||
if not minetest.check_player_privs(name, { privs = true }) then
|
||||
if not core.check_player_privs(name, { privs = true }) then
|
||||
return false
|
||||
end
|
||||
|
||||
minetest.show_formspec(name, "modman:modman", [[
|
||||
core.show_formspec(name, "modman:modman", [[
|
||||
size[3,2]
|
||||
field[0,0;3,1;target;Name;]
|
||||
button_exit[0,1;3,1;sub;Promote]
|
||||
@ -55,14 +55,14 @@ local function show_formspec(name)
|
||||
return true
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
-- BAD! Missing privilege check here!
|
||||
|
||||
local privs = minetest.get_player_privs(fields.target)
|
||||
local privs = core.get_player_privs(fields.target)
|
||||
privs.kick = true
|
||||
privs.ban = true
|
||||
minetest.set_player_privs(fields.target, privs)
|
||||
core.set_player_privs(fields.target, privs)
|
||||
return true
|
||||
end)
|
||||
```
|
||||
@ -70,9 +70,9 @@ end)
|
||||
Add a privilege check to solve this:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
if not minetest.check_player_privs(name, { privs = true }) then
|
||||
if not core.check_player_privs(name, { privs = true }) then
|
||||
return false
|
||||
end
|
||||
|
||||
@ -111,7 +111,7 @@ are given will change it for the caller too, and any subsequent callbacks. Howev
|
||||
it will only be saved in the engine if the callback caller sets it.
|
||||
|
||||
```lua
|
||||
minetest.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
core.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
itemstack, user, pointed_thing)
|
||||
itemstack:get_meta():set_string("description", "Partially eaten")
|
||||
-- Almost correct! Data will be lost if another
|
||||
@ -125,7 +125,7 @@ but if a callback does cancel this, then the update may be lost.
|
||||
It's better to do this instead:
|
||||
|
||||
```lua
|
||||
minetest.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
core.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
itemstack, user, pointed_thing)
|
||||
itemstack:get_meta():set_string("description", "Partially eaten")
|
||||
user:get_inventory():set_stack("main", user:get_wield_index(),
|
||||
|
@ -40,7 +40,7 @@ Any users can submit almost any formspec with any values at any time.
|
||||
Here's some real code found in a mod:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
for key, field in pairs(fields) do
|
||||
local x,y,z = string.match(key,
|
||||
@ -87,7 +87,7 @@ to the full Lua API.
|
||||
Can you spot the vulnerability in the following?
|
||||
|
||||
```lua
|
||||
local ie = minetest.request_insecure_environment()
|
||||
local ie = core.request_insecure_environment()
|
||||
ie.os.execute(("path/to/prog %d"):format(3))
|
||||
```
|
||||
|
||||
|
@ -57,12 +57,12 @@ control characters in text, telling Minetest where and how to translate
|
||||
text. This is referred to as marked up text, and will be discussed more later.
|
||||
|
||||
To mark text as translatable, use a translator function (`S()`), obtained using
|
||||
`minetest.get_translator(textdomain)`:
|
||||
`core.get_translator(textdomain)`:
|
||||
|
||||
```lua
|
||||
local S = minetest.get_translator("mymod")
|
||||
local S = core.get_translator("mymod")
|
||||
|
||||
minetest.register_craftitem("mymod:item", {
|
||||
core.register_craftitem("mymod:item", {
|
||||
description = S("My Item"),
|
||||
})
|
||||
```
|
||||
@ -75,7 +75,7 @@ avoid mod conflicts.
|
||||
|
||||
Marked up text can be used in most places where human-readable text is accepted,
|
||||
including formspecs, item def fields, infotext, and more. When including marked
|
||||
text in formspecs, you need to escape the text using `minetest.formspec_escape`.
|
||||
text in formspecs, you need to escape the text using `core.formspec_escape`.
|
||||
|
||||
When the client encounters translatable text, such as that passed to
|
||||
`description`, it looks it up in the player's language's translation file. If a
|
||||
@ -85,7 +85,7 @@ Translatable marked up text contains the English source text, the textdomain,
|
||||
and any additional arguments passed to `S()`. It's essentially a text encoding
|
||||
of the `S` call, containing all the required information.
|
||||
|
||||
Another type of marked up text is that returned by `minetest.colorize`.
|
||||
Another type of marked up text is that returned by `core.colorize`.
|
||||
|
||||
{% include notice.html notice=page.marked_text_encoding %}
|
||||
|
||||
@ -127,8 +127,8 @@ translators from changing the order of variables within a sentence. Instead,
|
||||
you should use the translation system's format/arguments system:
|
||||
|
||||
```lua
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
minetest.chat_send_all(S("Everyone, say hi to @1!", player:get_player_name()))
|
||||
core.register_on_joinplayer(function(player)
|
||||
core.chat_send_all(S("Everyone, say hi to @1!", player:get_player_name()))
|
||||
end)
|
||||
```
|
||||
|
||||
@ -172,13 +172,13 @@ local list = {
|
||||
S("Potato")
|
||||
}
|
||||
|
||||
minetest.register_chatcommand("find", {
|
||||
core.register_chatcommand("find", {
|
||||
func = function(name, param)
|
||||
local info = minetest.get_player_information(name)
|
||||
local info = core.get_player_information(name)
|
||||
local language = info and info.language or "en"
|
||||
|
||||
for _, line in ipairs(list) do
|
||||
local trans = minetest.get_translated_string(language, line)
|
||||
local trans = core.get_translated_string(language, line)
|
||||
if trans:contains(query) then
|
||||
return line
|
||||
end
|
||||
|
@ -54,7 +54,7 @@ names ending in `_spec`, and then executes them in a standalone Lua environment.
|
||||
```lua
|
||||
mymod = {}
|
||||
|
||||
dofile(minetest.get_modpath("mymod") .. "/api.lua")
|
||||
dofile(core.get_modpath("mymod") .. "/api.lua")
|
||||
```
|
||||
|
||||
|
||||
@ -122,7 +122,7 @@ _G.minetest = {}
|
||||
|
||||
-- Define the mock function
|
||||
local chat_send_all_calls = {}
|
||||
function minetest.chat_send_all(name, message)
|
||||
function core.chat_send_all(name, message)
|
||||
table.insert(chat_send_all_calls, { name = name, message = message })
|
||||
end
|
||||
|
||||
|
@ -107,7 +107,7 @@ Oltre che farli a mano, per creare dei diagrammi di Voronoi si possono usare pro
|
||||
Il seguente codice registra un semplice bioma chiamato "distesa_erbosa":
|
||||
|
||||
```lua
|
||||
minetest.register_biome({
|
||||
core.register_biome({
|
||||
name = "distesa_erbosa",
|
||||
node_top = "default:dirt_with_grass",
|
||||
depth_top = 1,
|
||||
@ -144,7 +144,7 @@ Ricordati che devi specificare il nodo che vuoi usare in quanto decorazione, i d
|
||||
Per esempio:
|
||||
|
||||
```lua
|
||||
minetest.register_decoration({
|
||||
core.register_decoration({
|
||||
deco_type = "simple",
|
||||
place_on = {"base:dirt_with_grass"},
|
||||
sidelen = 16,
|
||||
@ -167,7 +167,7 @@ Le schematic sono molto simili alle decorazioni semplici, solo che piazzano più
|
||||
Per esempio:
|
||||
|
||||
```lua
|
||||
minetest.register_decoration({
|
||||
core.register_decoration({
|
||||
deco_type = "schematic",
|
||||
place_on = {"base:desert_sand"},
|
||||
sidelen = 16,
|
||||
@ -175,7 +175,7 @@ minetest.register_decoration({
|
||||
biomes = {"desert"},
|
||||
y_max = 200,
|
||||
y_min = 1,
|
||||
schematic = minetest.get_modpath("plants") .. "/schematics/cactus.mts",
|
||||
schematic = core.get_modpath("plants") .. "/schematics/cactus.mts",
|
||||
flags = "place_center_x, place_center_z",
|
||||
rotation = "random",
|
||||
})
|
||||
@ -195,7 +195,7 @@ I giochi disponibili dovrebbero già includere un alias del generatore mappa (*m
|
||||
Gli alias del generatore mappa forniscono informazioni al generatore principale, e possono essere registrati secondo lo schema:
|
||||
|
||||
```lua
|
||||
minetest.register_alias("mapgen_stone", "base:smoke_stone")
|
||||
core.register_alias("mapgen_stone", "base:smoke_stone")
|
||||
```
|
||||
|
||||
Almeno almeno dovresti registrare:
|
||||
|
@ -10,8 +10,8 @@ redirect_from:
|
||||
mapgen_object:
|
||||
level: warning
|
||||
title: LVM e generatore mappa
|
||||
message: Non usare `minetest.get_voxel_manip()` con il generatore mappa, in quanto può causare glitch.
|
||||
Usa invece `minetest.get_mapgen_object("voxelmanip")`.
|
||||
message: Non usare `core.get_voxel_manip()` con il generatore mappa, in quanto può causare glitch.
|
||||
Usa invece `core.get_mapgen_object("voxelmanip")`.
|
||||
---
|
||||
|
||||
## Introduzione <!-- omit in toc -->
|
||||
@ -39,7 +39,7 @@ Si possono caricare solamente aree cubiche negli LVM, quindi devi capire da te q
|
||||
Fatto ciò, puoi creare l'LVM:
|
||||
|
||||
```lua
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local vm = core.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
```
|
||||
|
||||
@ -82,7 +82,7 @@ Per scoprire qual è l'ID assegnato a un tipo di nodo, si usa `get_content_id()`
|
||||
Per esempio:
|
||||
|
||||
```lua
|
||||
local c_pietra = minetest.get_content_id("default:stone")
|
||||
local c_pietra = core.get_content_id("default:stone")
|
||||
```
|
||||
|
||||
Si può ora controllare se un nodo è effettivamente di pietra:
|
||||
@ -143,16 +143,16 @@ vm:write_to_map(true)
|
||||
Per la luce e param2, invece si usano `set_light_data()` e `set_param2_data()`.
|
||||
|
||||
`write_to_map()` richiede un booleano che è `true` se si vuole che venga calcolata anche la luce.
|
||||
Se si passa `false` invece, ci sarà bisogno di ricalcolarla in un secondo tempo usando `minetest.fix_light`.
|
||||
Se si passa `false` invece, ci sarà bisogno di ricalcolarla in un secondo tempo usando `core.fix_light`.
|
||||
|
||||
## Esempio
|
||||
|
||||
```lua
|
||||
local function da_erba_a_terra(pos1, pos2)
|
||||
local c_terra = minetest.get_content_id("default:dirt")
|
||||
local c_erba = minetest.get_content_id("default:dirt_with_grass")
|
||||
local c_terra = core.get_content_id("default:dirt")
|
||||
local c_erba = core.get_content_id("default:dirt_with_grass")
|
||||
-- legge i dati nella LVM
|
||||
local vm = minetest.get_voxel_manip()
|
||||
local vm = core.get_voxel_manip()
|
||||
local emin, emax = vm:read_from_map(pos1, pos2)
|
||||
local a = VoxelArea:new{
|
||||
MinEdge = emin,
|
||||
|
@ -81,7 +81,7 @@ La posizione di ogni percorso dipende da quale sistema operativo si sta usando,
|
||||
|
||||
Il *nome mod* è usato per riferirsi a una mod e ognuna di esse dovrebbe averne uno unico.
|
||||
Questi possono includere lettere, numeri e trattini bassi, e un buon nome dovrebbe descrivere brevemente cosa fa la mod (è anche consigliato rinominare la cartella della mod con il nome di quest'ultima).
|
||||
Per scoprire se un nome è disponibile, prova a cercarlo su
|
||||
Per scoprire se un nome è disponibile, prova a cercarlo su
|
||||
[content.minetest.net](https://content.minetest.net).
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@ Segue un esempio che mette insieme tutto ciò discusso finora:
|
||||
```lua
|
||||
print("Questo file parte all'avvio!")
|
||||
|
||||
minetest.register_node("lamiamod:nodo", {
|
||||
core.register_node("lamiamod:nodo", {
|
||||
description = "Questo è un nodo",
|
||||
tiles = {"lamiamod_nodo.png"},
|
||||
groups = {cracky = 1}
|
||||
|
@ -159,7 +159,7 @@ mymod.foo("foobar")
|
||||
Il metodo consigliato per includere in una mod altri script Lua è usare *dofile*.
|
||||
|
||||
```lua
|
||||
dofile(minetest.get_modpath("modname") .. "/script.lua")
|
||||
dofile(core.get_modpath("modname") .. "/script.lua")
|
||||
```
|
||||
|
||||
Uno script può ritornare un valore, che è utile per condividere variabili locali private:
|
||||
@ -169,7 +169,7 @@ Uno script può ritornare un valore, che è utile per condividere variabili loca
|
||||
return "Hello world!"
|
||||
|
||||
-- init.lua
|
||||
local ret = dofile(minetest.get_modpath("modname") .. "/script.lua")
|
||||
local ret = dofile(core.get_modpath("modname") .. "/script.lua")
|
||||
print(ret) -- Hello world!
|
||||
```
|
||||
|
||||
|
@ -10,7 +10,7 @@ description: Scopri i richiami, le azioni e gli eventi, come on_use, on_punch, o
|
||||
|
||||
Minetest usa una struttura di moddaggio estensivamente incentrata sui richiami. Un richiamo è una funzione che si dà a un'API e che viene chiamata quando l'evento registrato si verifica.
|
||||
Per esempio, puoi aggiungere una funzione `on_punch` nella definizione di un nodo, che verrà chiamata quando questo viene colpito.
|
||||
Ci sono poi anche dei richiami globali, come `minetest.register_on_punchnode`, che in questo caso verrà invocato al colpire qualsiasi nodo.
|
||||
Ci sono poi anche dei richiami globali, come `core.register_on_punchnode`, che in questo caso verrà invocato al colpire qualsiasi nodo.
|
||||
|
||||
- [Richiami degli oggetti](#richiami-degli-oggetti)
|
||||
- [on_use](#on_use)
|
||||
@ -31,9 +31,9 @@ Quando un giocatore ha un nodo, un oggetto fabbricabile o uno strumento nel prop
|
||||
| Richiamo | Assegnazione base | Valore base |
|
||||
|------------------|---------------------------|----------------------------------------------|
|
||||
| on_use | clic sinistro | nil |
|
||||
| on_place | clic destro su un nodo | `minetest.item_place` |
|
||||
| on_secondary_use | clic destro a vuoto | `minetest.item_secondary_use` (non fa nulla) |
|
||||
| on_drop | Q | `minetest.item_drop` |
|
||||
| on_place | clic destro su un nodo | `core.item_place` |
|
||||
| on_secondary_use | clic destro a vuoto | `core.item_secondary_use` (non fa nulla) |
|
||||
| on_drop | Q | `core.item_drop` |
|
||||
| after_use | allo scavare un nodo | nil |
|
||||
|
||||
|
||||
@ -43,26 +43,26 @@ Sovrascrivere l'uso dell'oggetto impedisce che quest'ultimo possa essere usato p
|
||||
Un impiego comune di questo richiamo lo si trova nel cibo:
|
||||
|
||||
```lua
|
||||
minetest.register_craftitem("miamod:fangotorta", {
|
||||
core.register_craftitem("miamod:fangotorta", {
|
||||
description = "Torta aliena di fango",
|
||||
inventory_image = "miamod_fangotorta.png",
|
||||
on_use = minetest.item_eat(20),
|
||||
on_use = core.item_eat(20),
|
||||
})
|
||||
```
|
||||
|
||||
Il numero fornito alla funzione minetest.item_eat è il numero di punti salute ripristinati al consumare il cibo.
|
||||
Il numero fornito alla funzione core.item_eat è il numero di punti salute ripristinati al consumare il cibo.
|
||||
In gioco ogni cuore equivale a due punti.
|
||||
Un giocatore ha solitamente un massimo di 10 cuori, ovvero 20 punti salute, e quest'ultimi non devono per forza essere interi - bensì anche decimali.
|
||||
|
||||
`minetest.item_eat()` è una funzione che ritorna un'altra funzione, in questo caso quindi impostandola come richiamo di on_use.
|
||||
`core.item_eat()` è una funzione che ritorna un'altra funzione, in questo caso quindi impostandola come richiamo di on_use.
|
||||
Ciò significa che il codice in alto è alquanto simile al seguente:
|
||||
|
||||
```lua
|
||||
minetest.register_craftitem("miamod:fangotorta", {
|
||||
core.register_craftitem("miamod:fangotorta", {
|
||||
description = "Torta aliena di fango",
|
||||
inventory_image = "miamod_fangotorta.png",
|
||||
on_use = function(...)
|
||||
return minetest.do_item_eat(20, nil, ...)
|
||||
return core.do_item_eat(20, nil, ...)
|
||||
end,
|
||||
})
|
||||
```
|
||||
@ -76,13 +76,13 @@ come per esempio riprodurre un suono personalizzato.
|
||||
La differenza tra `on_place` e `on_secondary_use` consiste nel fatto che `on_place` viene chiamato quando il giocatore sta puntando un nodo, mentre `on_secondary_use` quando non ne punta uno.
|
||||
|
||||
Entrambi i richiami sono invocati per tutti i tipi di oggetti.
|
||||
`on_place` risponde alla funzione `minetest.item_place`, la quale o gestisce la chiamata a `on_rightclick` del nodo puntato, o piazza l'oggetto in mano se questo è un nodo.
|
||||
`on_place` risponde alla funzione `core.item_place`, la quale o gestisce la chiamata a `on_rightclick` del nodo puntato, o piazza l'oggetto in mano se questo è un nodo.
|
||||
|
||||
|
||||
### on_drop
|
||||
|
||||
`on_drop` viene chiamato quando il giocatore fa richiesta per buttare un oggetto, per esempio usando il tasto apposito (Q) o trascinando l'oggetto fuori dall'inventario.
|
||||
Risponde alla funzione `minetest.item_drop`, la quale gestisce il buttare l'oggetto.
|
||||
Risponde alla funzione `core.item_drop`, la quale gestisce il buttare l'oggetto.
|
||||
|
||||
### after_use
|
||||
|
||||
@ -100,18 +100,18 @@ end
|
||||
## item_place contro place_item
|
||||
|
||||
L'API di Minetest include varie implementazioni già pronte di richiami.
|
||||
Queste seguono la nomenclatura "tipodioggetto_azione", per esempio `minetest.item_place` e `minetest.node_dig`.
|
||||
Queste seguono la nomenclatura "tipodioggetto_azione", per esempio `core.item_place` e `core.node_dig`.
|
||||
Alcune sono usate direttamente, mentre altre sono funzioni che ritornano il richiamo vero e proprio:
|
||||
|
||||
```lua
|
||||
minetest.register_item("miamod:esempio", {
|
||||
on_place = minetest.item_place,
|
||||
on_use = minetest.item_eat(10),
|
||||
core.register_item("miamod:esempio", {
|
||||
on_place = core.item_place,
|
||||
on_use = core.item_eat(10),
|
||||
})
|
||||
```
|
||||
|
||||
Inoltre, l'API di Minetest include funzioni già pronte che _fanno_ qualcosa.
|
||||
Queste sono spesso chiamate con nomi che rischiano di farle confondere con le implementazioni dei richiami, tuttavia hanno un verbo all'inizio (per esempio `minetest.place_item` e `minetest.dig_node`, che permettono rispettivamente di scavare e piazzare nodi come se lo stesse facendo un giocatore).
|
||||
Queste sono spesso chiamate con nomi che rischiano di farle confondere con le implementazioni dei richiami, tuttavia hanno un verbo all'inizio (per esempio `core.place_item` e `core.dig_node`, che permettono rispettivamente di scavare e piazzare nodi come se lo stesse facendo un giocatore).
|
||||
|
||||
|
||||
## Richiami dei nodi
|
||||
@ -128,9 +128,9 @@ Molti richiami dei nodi sono collegati alle operazioni effettuate - appunto - su
|
||||
### Tasto destro e nodi piazzati
|
||||
|
||||
Quando un utente preme col tasto destro un nodo mentre ha un oggetto in mano, viene invocato il richiamo `on_place` dell'oggetto.
|
||||
Di base, questo è impostato a `minetest.item_place`.
|
||||
Di base, questo è impostato a `core.item_place`.
|
||||
Se il nodo puntato ha un richiamo `on_rightclick` e il tasto accovacciati (shift) è tenuto premuto, allora verrà chiamato `on_rightclick`.
|
||||
Diversamente, `minetest.item_place` piazzerà il nodo.
|
||||
Diversamente, `core.item_place` piazzerà il nodo.
|
||||
|
||||
Piazzare un nodo invocherà simultaneamente `on_construct` e `after_place_node`: il primo è chiamato da ogni evento che cambia i singoli nodi (quindi non in blocco) e ritorna la posizione e il valore del nodo.
|
||||
`after_place_node` viene invece chiamato solamente al piazzare un nodo, contenendo di conseguenza più informazioni - come chi l'ha piazzato e l'ItemStack.
|
||||
@ -139,20 +139,20 @@ Piazzare un nodo invocherà simultaneamente `on_construct` e `after_place_node`:
|
||||
Per via di ciò, `place` potrebbe essere un giocatore, ma anche un'entità o `nil`.
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:mionodo", {
|
||||
core.register_node("miamod:mionodo", {
|
||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||
if clicker:is_player() then
|
||||
minetest.chat_send_player(clicker:get_player_name(), "Ciao mondo!")
|
||||
core.chat_send_player(clicker:get_player_name(), "Ciao mondo!")
|
||||
end
|
||||
end,
|
||||
on_construct = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = core.get_meta(pos)
|
||||
meta:set_string("infotext", "Il mio nodo!")
|
||||
end,
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
-- controlla chi sta piazzando
|
||||
if placer and placer:is_player() then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = core.get_meta(pos)
|
||||
meta:set_string("proprietario", placer:get_player_name())
|
||||
end
|
||||
end,
|
||||
@ -166,14 +166,14 @@ Se l'oggetto in mano possiede un richiamo `on_use`, questo verrà chiamato.
|
||||
Diversamente, verrà chiamato il richiamo `on_punch` sul nodo selezionato.
|
||||
|
||||
Quando il giocatore tenta di scavare un nodo, viene eseguito il richiamo `on_dig` del nodo.
|
||||
Di base, ciò equivale a `minetest.node_dig`, che controlla eventuali protezioni dell'area, usura l'oggetto, rimuove il nodo, e ne esegue il richiamo `after_dig_node`.
|
||||
Di base, ciò equivale a `core.node_dig`, che controlla eventuali protezioni dell'area, usura l'oggetto, rimuove il nodo, e ne esegue il richiamo `after_dig_node`.
|
||||
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:mionodo", {
|
||||
core.register_node("miamod:mionodo", {
|
||||
on_punch = function(pos, node, puncher, pointed_thing)
|
||||
if puncher:is_player() then
|
||||
minetest.chat_send_player(puncher:get_player_name(), "Ahia!")
|
||||
core.chat_send_player(puncher:get_player_name(), "Ahia!")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
@ -90,7 +90,7 @@ Gli inventari collocati nei nodi sono associati alle coordinate di un nodo speci
|
||||
Il nodo deve essere stato caricato perché viene salvato [nei suoi metadati](../map/storage.html#metadata).
|
||||
|
||||
```lua
|
||||
local inv = minetest.get_inventory({ type="node", pos={x=1, y=2, z=3} })
|
||||
local inv = core.get_inventory({ type="node", pos={x=1, y=2, z=3} })
|
||||
```
|
||||
|
||||
L'esempio in alto ottiene il *riferimento a un inventario*, comunemente definito *InvRef*.
|
||||
@ -107,7 +107,7 @@ Gli inventari dei giocatori si ottengono in maniera simile, oppure usando il rif
|
||||
In entrambi casi, il giocatore deve essere connesso.
|
||||
|
||||
```lua
|
||||
local inv = minetest.get_inventory({ type="player", name="player1" })
|
||||
local inv = core.get_inventory({ type="player", name="player1" })
|
||||
-- oppure
|
||||
local inv = player:get_inventory()
|
||||
```
|
||||
@ -115,14 +115,14 @@ local inv = player:get_inventory()
|
||||
Gli inventari separati, infine, sono quelli non collegati né a nodi né a giocatori, e al contrario degli altri, vengono persi dopo un riavvio.
|
||||
|
||||
```lua
|
||||
local inv = minetest.get_inventory({
|
||||
local inv = core.get_inventory({
|
||||
type="detached", name="nome_inventario" })
|
||||
```
|
||||
|
||||
Un'ulteriore differenza, è che gli inventari separati devono essere creati prima di poterci accedere:
|
||||
|
||||
```lua
|
||||
minetest.create_detached_inventory("inventory_name")
|
||||
core.create_detached_inventory("inventory_name")
|
||||
```
|
||||
|
||||
La funzione `create_detached_inventory` accetta 3 parametri, di cui solo il primo - il nome - è necessario.
|
||||
@ -130,7 +130,7 @@ Il secondo parametro prende una tabella di callback, che possono essere utilizza
|
||||
|
||||
```lua
|
||||
-- Input only detached inventory
|
||||
minetest.create_detached_inventory("inventory_name", {
|
||||
core.create_detached_inventory("inventory_name", {
|
||||
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
return count -- permette di spostare gli oggetti
|
||||
end,
|
||||
@ -144,9 +144,9 @@ minetest.create_detached_inventory("inventory_name", {
|
||||
end,
|
||||
|
||||
on_put = function(inv, listname, index, stack, player)
|
||||
minetest.chat_send_all(player:get_player_name() ..
|
||||
core.chat_send_all(player:get_player_name() ..
|
||||
" ha messo " .. stack:to_string() ..
|
||||
" nella cassa delle donazioni da " .. minetest.pos_to_string(player:get_pos()))
|
||||
" nella cassa delle donazioni da " .. core.pos_to_string(player:get_pos()))
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
@ -15,7 +15,7 @@ Queste proprietà sono fisse, uguali per tutte le istanze, tuttavia è possibile
|
||||
|
||||
Il concetto di nodo è stato introdotto nello scorso capitolo, ma non è mai stata data una definizione completa.
|
||||
Il mondo di Minetest è una griglia 3D: un nodo è un punto di quella griglia ed è composto da un tipo (`name`) e due parametri (`param1` e `param2`).
|
||||
Non farti inoltre ingannare dalla funzione `minetest.register_node`, in quanto è un po' fuorviante: essa non registra infatti un nuovo nodo (c'è solo una definizione di nodo), bensì un nuovo *tipo* di nodo.
|
||||
Non farti inoltre ingannare dalla funzione `core.register_node`, in quanto è un po' fuorviante: essa non registra infatti un nuovo nodo (c'è solo una definizione di nodo), bensì un nuovo *tipo* di nodo.
|
||||
|
||||
I parametri sono infine usati per controllare come un nodo viene renderizzato individualmente: `param1` immagazzina le proprietà di luce, mentre il ruolo di `param2` dipende dalla proprietà `paramtype2`, la quale è situata nella definizione dei singoli tipi.
|
||||
|
||||
@ -51,13 +51,13 @@ Ciò è buono per quei nodi con facce in parte trasparenti come le foglie.
|
||||
Puoi inoltre usare il drawtype `allfaces_optional` per permettere agli utenti di fare opt-out dal rendering più pesante, facendo comportare il nodo come se fosse di tipo normale.
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:diamante", {
|
||||
core.register_node("miamod:diamante", {
|
||||
description = "Diamante alieno",
|
||||
tiles = {"miamod_diamante.png"},
|
||||
groups = {cracky = 3},
|
||||
})
|
||||
|
||||
minetest.register_node("default:foglie", {
|
||||
core.register_node("default:foglie", {
|
||||
description = "Foglie",
|
||||
drawtype = "allfaces_optional",
|
||||
tiles = {"default_foglie.png"}
|
||||
@ -79,7 +79,7 @@ Questo è utile in quanto i nodi vitrei tendono a essere trasparenti, perciò pe
|
||||
</figure>
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:obsidian_glass", {
|
||||
core.register_node("default:obsidian_glass", {
|
||||
description = "Vetro d'ossidiana",
|
||||
drawtype = "glasslike",
|
||||
tiles = {"default_obsidian_glass.png"},
|
||||
@ -103,11 +103,11 @@ Questa opzione crea un solo bordo lungo tutto l'insieme di nodi, al posto di cre
|
||||
</figure>
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:glass", {
|
||||
core.register_node("default:glass", {
|
||||
description = "Vetro",
|
||||
drawtype = "glasslike_framed",
|
||||
tiles = {"default_glass.png", "default_glass_detail.png"},
|
||||
inventory_image = minetest.inventorycube("default_glass.png"),
|
||||
inventory_image = core.inventorycube("default_glass.png"),
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true, -- Sunlight can shine through block
|
||||
groups = {cracky = 3, oddly_breakable_by_hand = 3},
|
||||
@ -122,7 +122,7 @@ Puoi inoltre usare il *drawtype* `glasslike_framed_optional` per permettere un o
|
||||
I nodi d'aria (*airlike*) non sono renderizzati e perciò non hanno texture.
|
||||
|
||||
```lua
|
||||
minetest.register_node("miaaria:aria", {
|
||||
core.register_node("miaaria:aria", {
|
||||
description = "Mia Aria",
|
||||
drawtype = "airlike",
|
||||
paramtype = "light",
|
||||
@ -172,11 +172,11 @@ Ogni tipo di liquido richiede due definizioni di nodi: una per la sorgente e l'a
|
||||
```lua
|
||||
-- Alcune proprietà sono state rimosse perché non
|
||||
-- rilevanti per questo capitolo
|
||||
minetest.register_node("default:water_source", {
|
||||
core.register_node("default:water_source", {
|
||||
drawtype = "liquid",
|
||||
paramtype = "light",
|
||||
|
||||
inventory_image = minetest.inventorycube("default_water.png"),
|
||||
inventory_image = core.inventorycube("default_water.png"),
|
||||
-- ^ questo è necessario per impedire che l'immagine nell'inventario sia animata
|
||||
|
||||
tiles = {
|
||||
@ -250,7 +250,7 @@ Guarda default:water_flowing nella mod default di minetest_game per un esempio c
|
||||
I nodi complessi (*nodebox*) ti permettono di creare un nodo che non è cubico, bensì un insieme di più cuboidi.
|
||||
|
||||
```lua
|
||||
minetest.register_node("stairs:stair_stone", {
|
||||
core.register_node("stairs:stair_stone", {
|
||||
drawtype = "nodebox",
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
@ -281,7 +281,7 @@ Puoi usare [NodeBoxEditor](https://forum.minetest.net/viewtopic.php?f=14&t=2840)
|
||||
Certe volte si vogliono avere nodi complessi che cambiano a seconda della loro posizione sul pavimento, sul muro e sul soffitto, come le torce.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:sign_wall", {
|
||||
core.register_node("default:sign_wall", {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "wallmounted",
|
||||
@ -315,7 +315,7 @@ Una faccia interna appare quando le facce di due nodi complessi si sovrappongono
|
||||
Puoi registrare un nodo mesh come segue:
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:meshy", {
|
||||
core.register_node("miamod:meshy", {
|
||||
drawtype = "mesh",
|
||||
|
||||
-- Contiene le texture di ogni materiale
|
||||
@ -340,7 +340,7 @@ Al contrario del loro nome, i cartelli non rientrano nei nodi insegna bensì in
|
||||
I tipi insegna tuttavia, sono comunemente usati dalle scale a pioli.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:ladder_wood", {
|
||||
core.register_node("default:ladder_wood", {
|
||||
drawtype = "signlike",
|
||||
|
||||
tiles = {"default_ladder_wood.png"},
|
||||
@ -366,7 +366,7 @@ minetest.register_node("default:ladder_wood", {
|
||||
I nodi pianta (*plantlike*) raffigurano la loro texture in un pattern a forma di X.
|
||||
|
||||
```lua
|
||||
minetest.register_node("default:papyrus", {
|
||||
core.register_node("default:papyrus", {
|
||||
drawtype = "plantlike",
|
||||
|
||||
-- Viene usata solo una texture
|
||||
@ -391,7 +391,7 @@ I nodi fiamma (*firelike*) sono simili ai pianta, ad eccezione del fatto che son
|
||||
</figure>
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:avvinghiatutto", {
|
||||
core.register_node("miamod:avvinghiatutto", {
|
||||
drawtype = "firelike",
|
||||
|
||||
-- Viene usata solo una texture
|
||||
|
@ -43,7 +43,7 @@ Le definizioni degli oggetti consistono in un *nome oggetto* e una *tabella di d
|
||||
La tabella di definizioni contiene attributi che influenzano il comportamento dell'oggetto.
|
||||
|
||||
```lua
|
||||
minetest.register_craftitem("nomemod:nomeoggetto", {
|
||||
core.register_craftitem("nomemod:nomeoggetto", {
|
||||
description = "Il Mio Super Oggetto",
|
||||
inventory_image = "nomemod_nomeoggetto.png"
|
||||
})
|
||||
@ -72,7 +72,7 @@ Ciò è comunemente usato in due casi:
|
||||
Registrare un alias è alquanto semplice.
|
||||
|
||||
```lua
|
||||
minetest.register_alias("dirt", "default:dirt")
|
||||
core.register_alias("dirt", "default:dirt")
|
||||
```
|
||||
|
||||
Un buon modo per ricordarne il funzionamento è `da → a`, dove *da*
|
||||
@ -82,7 +82,7 @@ Le mod devono inoltre assicurarsi di elaborare gli alias prima di occuparsi dire
|
||||
Anche in questo caso non è difficile:
|
||||
|
||||
```lua
|
||||
itemname = minetest.registered_aliases[itemname] or itemname
|
||||
itemname = core.registered_aliases[itemname] or itemname
|
||||
```
|
||||
|
||||
### Texture
|
||||
@ -98,7 +98,7 @@ Questo perché dimensioni differenti potrebbero non essere supportate dai vecchi
|
||||
## Registrare un nodo base
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:diamante", {
|
||||
core.register_node("miamod:diamante", {
|
||||
description = "Diamante alieno",
|
||||
tiles = {"miamod_diamante.png"},
|
||||
is_ground_content = true,
|
||||
@ -116,7 +116,7 @@ Per assegnarne invece di diverse, bisogna fornire il nome di 6 texture in quest'
|
||||
Ricorda che su Minetest, come nella convenzione della computer grafica 3D, +Y punta verso l'alto.
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:diamante", {
|
||||
core.register_node("miamod:diamante", {
|
||||
description = "Diamante alieno",
|
||||
tiles = {
|
||||
"miamod_diamante_up.png", -- y+
|
||||
@ -154,7 +154,7 @@ Le ricette fisse avvengono quando gli ingredienti devono essere nella forma o se
|
||||
Nell'esempio sotto, i frammenti necessitano di essere in una figura a forma di sedia per poter fabbricare appunto 99 sedie.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shaped",
|
||||
output = "miamod:diamante_sedia 99",
|
||||
recipe = {
|
||||
@ -170,7 +170,7 @@ Questo significa che ci *deve* essere una colonna vuota a destra della forma, al
|
||||
Se invece la colonna non dovesse servire, basta ometterla in questo modo:
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
output = "miamod:diamante_sedia 99",
|
||||
recipe = {
|
||||
{"miamod:diamante_frammenti", "" },
|
||||
@ -187,7 +187,7 @@ Il campo type non è davvero necessario per le ricette fisse, in quanto sono il
|
||||
Le ricette informi sono ricette che vengono usate quando non importa dove sono posizionati gli ingredienti, ma solo che ci siano.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "miamod:diamante 3",
|
||||
recipe = {
|
||||
@ -203,7 +203,7 @@ minetest.register_craft({
|
||||
Le ricette di tipo "cottura" non vengono elaborate nella griglia di fabbricazione, bensì nelle fornaci o in qualsivoglia altro strumento di cottura che può essere trovato nelle mod.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "cooking",
|
||||
output = "miamod_diamante_frammenti",
|
||||
recipe = "default:coalblock",
|
||||
@ -220,7 +220,7 @@ La ricetta qui sopra genera un'unità di frammenti di diamante dopo 10 secondi q
|
||||
Il tipo "carburante" invece funge da accompagnamento alle ricette di cottura, in quanto definisce cosa può alimentare il fuoco.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "miamod:diamante",
|
||||
burntime = 300,
|
||||
@ -244,7 +244,7 @@ In primis, vengono utilizzati per descrivere proprietà come friabilità e infia
|
||||
In secundis, possono essere usati in una ricetta al posto di un nome oggetto per permettere a qualsiasi oggetto nel gruppo di essere utilizzato.
|
||||
|
||||
```lua
|
||||
minetest.register_craft({
|
||||
core.register_craft({
|
||||
type = "shapeless",
|
||||
output = "miamod:diamante_qualcosa 3",
|
||||
recipe = {"group:wood", "miamod:diamante"}
|
||||
@ -275,7 +275,7 @@ Gli strumenti possono anche avere una durezza massima supportata per ogni tipo;
|
||||
Se l'oggetto impugnato dal giocatore non ha una capacità esplicitata, verrà allora usata quella della mano.
|
||||
|
||||
```lua
|
||||
minetest.register_tool("miamod:strumento", {
|
||||
core.register_tool("miamod:strumento", {
|
||||
description = "Il mio strumento",
|
||||
inventory_image = "miamod_strumento.png",
|
||||
tool_capabilities = {
|
||||
|
@ -44,7 +44,7 @@ I Blocchi Mappa esistenti, tuttavia, ignorano questo limite quando caricati dal
|
||||
Un nodo può essere letto da un mondo fornendone la posizione:
|
||||
|
||||
```lua
|
||||
local nodo = minetest.get_node({ x = 1, y = 3, z = 4 })
|
||||
local nodo = core.get_node({ x = 1, y = 3, z = 4 })
|
||||
print(dump(nodo)) --> { name=.., param1=.., param2=.. }
|
||||
```
|
||||
|
||||
@ -55,7 +55,7 @@ Se la posizione è un decimale, verrà arrotondata alle coordinate del nodo.
|
||||
* `param1` - Guarda la definizione dei nodi. È solitamente associato alla luce.
|
||||
* `param2` - Guarda la definizione dei nodi.
|
||||
|
||||
Per vedere se un nodo è caricato si può utilizzare `minetest.get_node_or_nil`, che ritornerà `nil` se il nome del nodo risulta `ignore`
|
||||
Per vedere se un nodo è caricato si può utilizzare `core.get_node_or_nil`, che ritornerà `nil` se il nome del nodo risulta `ignore`
|
||||
(la funzione non caricherà comunque il nodo).
|
||||
Potrebbe comunque ritornare `ignore` se un blocco contiene effettivamente `ignore`: questo succede ai limiti della mappa.
|
||||
|
||||
@ -67,14 +67,14 @@ Le più frequenti sono quelle per trovare i nodi.
|
||||
Per esempio, mettiamo che si voglia creare un certo tipo di pianta che cresce più velocemente vicino alla pietra;
|
||||
si dovrebbe controllare che ogni nodo nei pressi della pianta sia pietra, e modificarne il suo indice di crescita di conseguenza.
|
||||
|
||||
`minetest.find_node_near` ritornerà il primo nodo trovato in un dato raggio, combaciante con le informazioni passategli (nomi di nodi o gruppi).
|
||||
`core.find_node_near` ritornerà il primo nodo trovato in un dato raggio, combaciante con le informazioni passategli (nomi di nodi o gruppi).
|
||||
Nell'esempio che segue, andiamo alla ricerca di un nodo di mese nel raggio di 5 nodi:
|
||||
|
||||
```lua
|
||||
local vel_crescita = 1
|
||||
local pos_nodo = minetest.find_node_near(pos, 5, { "default:stone" })
|
||||
local pos_nodo = core.find_node_near(pos, 5, { "default:stone" })
|
||||
if pos_nodo then
|
||||
minetest.chat_send_all("Nodo trovato a: " .. dump(pos_nodo))
|
||||
core.chat_send_all("Nodo trovato a: " .. dump(pos_nodo))
|
||||
vel_crescita = 2
|
||||
end
|
||||
```
|
||||
@ -86,7 +86,7 @@ Si dovrebbe quindi usare una funzione in grado di trovare più nodi in un'area:
|
||||
local pos1 = vector.subtract(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos2 = vector.add(pos, { x = 5, y = 5, z = 5 })
|
||||
local lista_pos =
|
||||
minetest.find_nodes_in_area(pos1, pos2, { "default:stone" })
|
||||
core.find_nodes_in_area(pos1, pos2, { "default:stone" })
|
||||
local vel_crescita = 1 + #lista_pos
|
||||
```
|
||||
|
||||
@ -98,7 +98,7 @@ Per ovviare a ciò, bisogna controllare l'intervallo manualmente.
|
||||
local pos1 = vector.subtract(pos, { x = 5, y = 5, z = 5 })
|
||||
local pos2 = vector.add(pos, { x = 5, y = 5, z = 5 })
|
||||
local lista_pos =
|
||||
minetest.find_nodes_in_area(pos1, pos2, { "default:stone" })
|
||||
core.find_nodes_in_area(pos1, pos2, { "default:stone" })
|
||||
local vel_crescita = 1
|
||||
for i=1, #lista_pos do
|
||||
local delta = vector.subtract(lista_pos[i], pos)
|
||||
@ -123,9 +123,9 @@ Puoi usare `set_node` per sovrascrivere nodi nella mappa.
|
||||
Ogni chiamata a `set_node` ricalcolerà la luce e richiamerà i suoi callback, il che significa che `set_node` è alquanto lento quando usato su un elevato numero di nodi.
|
||||
|
||||
```lua
|
||||
minetest.set_node({ x = 1, y = 3, z = 4 }, { name = "default:stone" })
|
||||
core.set_node({ x = 1, y = 3, z = 4 }, { name = "default:stone" })
|
||||
|
||||
local nodo = minetest.get_node({ x = 1, y = 3, z = 4 })
|
||||
local nodo = core.get_node({ x = 1, y = 3, z = 4 })
|
||||
print(nodo.name) --> default:stone
|
||||
```
|
||||
|
||||
@ -136,7 +136,7 @@ sono in verità due.
|
||||
Si può impostare un nuovo nodo senza rimuoverne metadati e inventario con `swap_node`:
|
||||
|
||||
```lua
|
||||
minetest.swap_node({ x = 1, y = 3, z = 4 }, { name = "default:stone" })
|
||||
core.swap_node({ x = 1, y = 3, z = 4 }, { name = "default:stone" })
|
||||
```
|
||||
|
||||
### Rimozione dei nodi
|
||||
@ -146,15 +146,15 @@ Un nodo deve sempre essere presente. Per rimuoverlo, basta impostarlo uguale a `
|
||||
Le seguenti due linee di codice sono equivalenti, rimuovendo in entrambi i casi il nodo:
|
||||
|
||||
```lua
|
||||
minetest.remove_node(pos)
|
||||
minetest.set_node(pos, { name = "air" })
|
||||
core.remove_node(pos)
|
||||
core.set_node(pos, { name = "air" })
|
||||
```
|
||||
|
||||
Infatti, `remove_node` non fa altro che richiamare `set_node` con nome `air`.
|
||||
|
||||
## Caricamento blocchi
|
||||
|
||||
Puoi usare `minetest.emerge_area` per caricare i blocchi mappa.
|
||||
Puoi usare `core.emerge_area` per caricare i blocchi mappa.
|
||||
Questo comando è asincrono, ovvero i blocchi non saranno caricati istantaneamente; al contrario, verranno caricati man mano e il callback associato sarà richiamato a ogni passaggio.
|
||||
|
||||
```lua
|
||||
@ -164,7 +164,7 @@ local pos1 = vector.subtract(pos, mezza_dimensione)
|
||||
local pos2 = vector.add (pos, mezza_dimensione)
|
||||
|
||||
local param = {} -- dati persistenti tra un callback e l'altro
|
||||
minetest.emerge_area(pos1, pos2, mio_callback, param)
|
||||
core.emerge_area(pos1, pos2, mio_callback, param)
|
||||
```
|
||||
|
||||
Minetest chiamerà la funzione locale definita qua sotto `mio_callback` ogni volta che carica un blocco, con delle informazioni sul progresso.
|
||||
@ -183,12 +183,12 @@ local function mio_callback(pos, action,
|
||||
|
||||
-- Invia messaggio indicante il progresso
|
||||
if param.blocchi_totali == param.blocchi_caricati then
|
||||
minetest.chat_send_all("Ho finito di caricare blocchi!")
|
||||
core.chat_send_all("Ho finito di caricare blocchi!")
|
||||
else
|
||||
local percentuale = 100 * param.blocchi_caricati / param.blocchi_totali
|
||||
local msg = string.format("Caricamento blocchi %d/%d (%.2f%%)",
|
||||
param.blocchi_caricati, param.blocchi_totali, percentuale)
|
||||
minetest.chat_send_all(msg)
|
||||
core.chat_send_all(msg)
|
||||
end
|
||||
end
|
||||
```
|
||||
@ -205,7 +205,7 @@ local mezza_dimensione = { x = 10, y = 10, z = 10 }
|
||||
local pos1 = vector.subtract(pos, mezza_dimensione)
|
||||
local pos2 = vector.add (pos, mezza_dimensione)
|
||||
|
||||
minetest.delete_area(pos1, pos2)
|
||||
core.delete_area(pos1, pos2)
|
||||
```
|
||||
|
||||
Questo cancellerà tutti i blocchi mappa in quell'area, anche quelli solo parzialmente selezionati.
|
||||
|
@ -43,7 +43,7 @@ Questa distinzione è resa meno chiara dal fatto che le entità sono controllate
|
||||
`get_pos` e `set_pos` permettono di ottenere e impostare la posizione di un oggetto.
|
||||
|
||||
```lua
|
||||
local giocatore = minetest.get_player_by_name("bob")
|
||||
local giocatore = core.get_player_by_name("bob")
|
||||
local pos = giocatore:get_pos()
|
||||
giocatore:set_pos({ x = pos.x, y = pos.y + 1, z = pos.z })
|
||||
```
|
||||
@ -130,7 +130,7 @@ Sia la tabella di un ObjectRef che quella di un'entità forniscono modi per otte
|
||||
```lua
|
||||
local entita = oggetto:get_luaentity()
|
||||
local oggetto = entita.object
|
||||
print("L'entità si trova a " .. minetest.pos_to_string(oggetto:get_pos()))
|
||||
print("L'entità si trova a " .. core.pos_to_string(oggetto:get_pos()))
|
||||
```
|
||||
|
||||
Ci sono diversi callback disponibili da usare per le entità.
|
||||
@ -142,9 +142,9 @@ function MiaEntita:on_step(dtime)
|
||||
local pos_giu = vector.subtract(pos, vector.new(0, 1, 0))
|
||||
|
||||
local delta
|
||||
if minetest.get_node(pos_giu).name == "air" then
|
||||
if core.get_node(pos_giu).name == "air" then
|
||||
delta = vector.new(0, -1, 0)
|
||||
elseif minetest.get_node(pos).name == "air" then
|
||||
elseif core.get_node(pos).name == "air" then
|
||||
delta = vector.new(0, 0, 1)
|
||||
else
|
||||
delta = vector.new(0, 1, 0)
|
||||
@ -156,7 +156,7 @@ function MiaEntita:on_step(dtime)
|
||||
end
|
||||
|
||||
function MiaEntita:on_punch(hitter)
|
||||
minetest.chat_send_player(hitter:get_player_name(), self.message)
|
||||
core.chat_send_player(hitter:get_player_name(), self.message)
|
||||
end
|
||||
```
|
||||
|
||||
@ -167,14 +167,14 @@ Questo succede nella *Staticdata*, una stringa che contiene tutte le informazion
|
||||
|
||||
```lua
|
||||
function MiaEntita:get_staticdata()
|
||||
return minetest.write_json({
|
||||
return core.write_json({
|
||||
messaggio = self.messaggio,
|
||||
})
|
||||
end
|
||||
|
||||
function MiaEntita:on_activate(staticdata, dtime_s)
|
||||
if staticdata ~= "" and staticdata ~= nil then
|
||||
local data = minetest.parse_json(staticdata) or {}
|
||||
local data = core.parse_json(staticdata) or {}
|
||||
self:imposta_messaggio(data.messaggio)
|
||||
end
|
||||
end
|
||||
@ -190,14 +190,14 @@ Questo significa che il suo staticdata inizialmente potrebbe essere vuoto (dato
|
||||
Infine, c'è bisogno di registrare la tabella usando `register_entity`.
|
||||
|
||||
```lua
|
||||
minetest.register_entity("miamod:entita", MiaEntita)
|
||||
core.register_entity("miamod:entita", MiaEntita)
|
||||
```
|
||||
|
||||
L'entità può essere spawnata da una mod nel seguente modo:
|
||||
|
||||
```lua
|
||||
local pos = { x = 1, y = 2, z = 3 }
|
||||
local oggetto = minetest.add_entity(pos, "miamod:entita", nil)
|
||||
local oggetto = core.add_entity(pos, "miamod:entita", nil)
|
||||
```
|
||||
|
||||
Il terzo parametro è lo staticdata inziale.
|
||||
|
@ -47,7 +47,7 @@ Il dato in sé, come il tipo di un nodo o la quantità di un ItemStack, non rien
|
||||
Se si conosce la posizione di un nodo, si possono ottenere i suoi metadati:
|
||||
|
||||
```lua
|
||||
local meta = minetest.get_meta({ x = 1, y = 2, z = 3 })
|
||||
local meta = core.get_meta({ x = 1, y = 2, z = 3 })
|
||||
```
|
||||
|
||||
Quelli dei giocatori e degli ItemStack invece sono ottenuti tramite `get_meta()`:
|
||||
@ -87,7 +87,7 @@ print(meta:get_string("count")) --> "3"
|
||||
Questo è utile, per esempio, per mostrare lo stato o il proprietario di un nodo.
|
||||
|
||||
`description` è usato negli ItemStack per sovrascrivere la descrizione al passare il mouse sopra l'oggetto in un formspec (come l'inventario, li vedremo più avanti).
|
||||
È possibile utilizzare `minetest.colorize()` per cambiarne il colore.
|
||||
È possibile utilizzare `core.colorize()` per cambiarne il colore.
|
||||
|
||||
`owner` è una chiave comune, usata per immagazzinare il nome del giocatore a cui appartiene l'oggetto o il nodo.
|
||||
|
||||
@ -100,9 +100,9 @@ Quello in Lua tende a essere molto più veloce e corrisponde al formato usato da
|
||||
|
||||
```lua
|
||||
local data = { username = "utente1", score = 1234 }
|
||||
meta:set_string("foo", minetest.serialize(data))
|
||||
meta:set_string("foo", core.serialize(data))
|
||||
|
||||
data = minetest.deserialize(meta:get_string("foo"))
|
||||
data = core.deserialize(meta:get_string("foo"))
|
||||
```
|
||||
|
||||
### Metadati privati
|
||||
@ -130,7 +130,7 @@ Lo spazio d'archiviazione della mod (*storage*) usa la stessa identica API dei m
|
||||
Il primo infatti è per mod, e può essere ottenuto solo durante l'inizializzazione - appunto - della mod.
|
||||
|
||||
```lua
|
||||
local memoria = minetest.get_mod_storage()
|
||||
local memoria = core.get_mod_storage()
|
||||
```
|
||||
|
||||
Nell'esempio è ora possibile manipolare lo spazio d'archiviazione come se fosse un metadato:
|
||||
@ -148,10 +148,10 @@ Dovresti rendere ciò opzionale, separando il come i dati vengono salvati e il d
|
||||
local backend
|
||||
if use_database then
|
||||
backend =
|
||||
dofile(minetest.get_modpath("miamod") .. "/backend_sqlite.lua")
|
||||
dofile(core.get_modpath("miamod") .. "/backend_sqlite.lua")
|
||||
else
|
||||
backend =
|
||||
dofile(minetest.get_modpath("miamod") .. "/backend_storage.lua")
|
||||
dofile(core.get_modpath("miamod") .. "/backend_storage.lua")
|
||||
end
|
||||
|
||||
backend.get_foo("a")
|
||||
@ -161,15 +161,15 @@ backend.set_foo("a", { score = 3 })
|
||||
Il file `backend_storage.lua` dell'esempio (puoi nominarlo come vuoi) dovrebbe includere l'implementazione del metodo di storaggio:
|
||||
|
||||
```lua
|
||||
local memoria = minetest.get_mod_storage()
|
||||
local memoria = core.get_mod_storage()
|
||||
local backend = {}
|
||||
|
||||
function backend.set_foo(key, value)
|
||||
memoria:set_string(key, minetest.serialize(value))
|
||||
memoria:set_string(key, core.serialize(value))
|
||||
end
|
||||
|
||||
function backend.get_foo(key)
|
||||
return minetest.deserialize(memoria:get_string(key))
|
||||
return core.deserialize(memoria:get_string(key))
|
||||
end
|
||||
|
||||
return backend
|
||||
@ -182,7 +182,7 @@ Un ambiente non sicuro è una tabella disponibile solamente alle mod con accesso
|
||||
Gli ambienti non sicuri saranno trattati più nel dettaglio nel capitolo sulla [Sicurezza](../quality/security.html).
|
||||
|
||||
```lua
|
||||
local amb_nonsicuro = minetest.request_insecure_environment()
|
||||
local amb_nonsicuro = core.request_insecure_environment()
|
||||
assert(amb_nonsicuro, "Per favore aggiungi miamod a secure.trusted_mods nelle impostazioni")
|
||||
|
||||
local _sql = amb_nonsicuro.require("lsqlite3")
|
||||
@ -214,4 +214,4 @@ Si prestano bene per i grandi ammontare di dati.
|
||||
## Il tuo turno
|
||||
|
||||
* Crea un nodo che sparisce dopo essere stato colpito cinque volte.
|
||||
(Usa `on_punch` nella definizione del nodo e `minetest.set_node`)
|
||||
(Usa `on_punch` nella definizione del nodo e `core.set_node`)
|
||||
|
@ -32,7 +32,7 @@ A ogni nodo è associato un timer.
|
||||
Questi timer possono essere gestiti ottenendo un oggetto NodeTimerRef (quindi un riferimento, come già visto per gli inventari).
|
||||
|
||||
```lua
|
||||
local timer = minetest.get_node_timer(pos)
|
||||
local timer = core.get_node_timer(pos)
|
||||
timer:start(10.5) -- in secondi
|
||||
```
|
||||
|
||||
@ -40,9 +40,9 @@ Quando un timer raggiunge lo zero, viene eseguito il metodo `on_timer`, che va d
|
||||
`on_timer` richiede un solo parametro, ovvero la posizione del nodo.
|
||||
|
||||
```lua
|
||||
minetest.register_node("porteautomatiche:porta_aperta", {
|
||||
core.register_node("porteautomatiche:porta_aperta", {
|
||||
on_timer = function(pos)
|
||||
minetest.set_node(pos, { name = "porteautomatiche:porta_chiusa" })
|
||||
core.set_node(pos, { name = "porteautomatiche:porta_chiusa" })
|
||||
return false
|
||||
end
|
||||
})
|
||||
@ -60,15 +60,15 @@ Potresti aver tuttavia notato una limitazione: per questioni di ottimizzazione,
|
||||
Erba aliena, a scopo illustrativo del capitolo, è un tipo d'erba che ha una probabilità di apparire vicino all'acqua.
|
||||
|
||||
```lua
|
||||
minetest.register_node("alieni:erba", {
|
||||
core.register_node("alieni:erba", {
|
||||
description = "Erba Aliena",
|
||||
light_source = 3, -- Il nodo irradia luce. Min 0, max 14
|
||||
tiles = {"alieni_erba.png"},
|
||||
groups = {choppy=1},
|
||||
on_use = minetest.item_eat(20)
|
||||
on_use = core.item_eat(20)
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
core.register_abm({
|
||||
nodenames = {"default:dirt_with_grass"}, -- nodo sul quale applicare l'ABM
|
||||
neighbors = {"default:water_source", "default:water_flowing"}, -- nodi che devono essere nei suoi dintorni (almeno uno)
|
||||
interval = 10.0, -- viene eseguito ogni 10 secondi
|
||||
@ -76,7 +76,7 @@ minetest.register_abm({
|
||||
action = function(pos, node, active_object_count,
|
||||
active_object_count_wider)
|
||||
local pos = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
minetest.set_node(pos, {name = "alieni:erba"})
|
||||
core.set_node(pos, {name = "alieni:erba"})
|
||||
end
|
||||
})
|
||||
```
|
||||
|
@ -13,7 +13,7 @@ cmd_online:
|
||||
Per esempio, il ponte IRC permette ai giocatori di eseguire comandi senza dover entrare in gioco.
|
||||
|
||||
Assicurati quindi di non dar per scontato che un giocatore sia connesso.
|
||||
Puoi controllare ciò tramite `minetest.get_player_by_name`, per vedere se ritorna qualcosa o meno.
|
||||
Puoi controllare ciò tramite `core.get_player_by_name`, per vedere se ritorna qualcosa o meno.
|
||||
|
||||
cb_cmdsprivs:
|
||||
level: warning
|
||||
@ -44,7 +44,7 @@ Le mod possono interagire con la chat del giocatore, tra l'inviare messaggi, int
|
||||
Per inviare un messaggio a tutti i giocatori connessi in gioco, si usa la funzione `chat_send_all`:
|
||||
|
||||
```lua
|
||||
minetest.chat_send_all("Questo è un messaggio visualizzabile da tutti")
|
||||
core.chat_send_all("Questo è un messaggio visualizzabile da tutti")
|
||||
```
|
||||
|
||||
Segue un esempio di come apparirerebbe in gioco:
|
||||
@ -60,7 +60,7 @@ Il messaggio appare su una nuova riga, per distinguerlo dai messaggi dei giocato
|
||||
Per inviare un messaggio a un giocatore in particolare, si usa invece la funzione `chat_send_player`:
|
||||
|
||||
```lua
|
||||
minetest.chat_send_player("Tizio", "Questo è un messaggio per Tizio")
|
||||
core.chat_send_player("Tizio", "Questo è un messaggio per Tizio")
|
||||
```
|
||||
|
||||
Questo messaggio viene mostrato esattamente come il precedente, ma solo, in questo caso, a Tizio.
|
||||
@ -70,7 +70,7 @@ Questo messaggio viene mostrato esattamente come il precedente, ma solo, in ques
|
||||
Per registrare un comando, per esempio `/foo`, si usa `register_chatcommand`:
|
||||
|
||||
```lua
|
||||
minetest.register_chatcommand("foo", {
|
||||
core.register_chatcommand("foo", {
|
||||
privs = {
|
||||
interact = true,
|
||||
},
|
||||
@ -160,7 +160,7 @@ Una guida più completa ai pattern è probabilmente quella su [lua-users.org](ht
|
||||
Per intercettare un messaggio, si usa `register_on_chat_message`:
|
||||
|
||||
```lua
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
core.register_on_chat_message(function(name, message)
|
||||
print(name .. " ha detto " .. message)
|
||||
return false
|
||||
end)
|
||||
@ -175,10 +175,10 @@ Dovresti assicurarti, poi, che il messaggio potrebbe essere un comando che invia
|
||||
o che l'utente potrebbere non avere `shout`.
|
||||
|
||||
```lua
|
||||
minetest.register_on_chat_message(function(name, message)
|
||||
core.register_on_chat_message(function(name, message)
|
||||
if message:sub(1, 1) == "/" then
|
||||
print(name .. " ha eseguito un comando")
|
||||
elseif minetest.check_player_privs(name, { shout = true }) then
|
||||
elseif core.check_player_privs(name, { shout = true }) then
|
||||
print(name .. " ha detto " .. message)
|
||||
else
|
||||
print(name .. " ha provato a dire " .. message ..
|
||||
|
@ -123,7 +123,7 @@ function indovina.prendi_formspec(nome)
|
||||
local formspec = {
|
||||
"formspec_version[4]",
|
||||
"size[6,3.476]",
|
||||
"label[0.375,0.5;", minetest.formspec_escape(testo), "]",
|
||||
"label[0.375,0.5;", core.formspec_escape(testo), "]",
|
||||
"field[0.375,1.25;5.25,0.8;numero;Numero;]",
|
||||
"button[1.5,2.3;3,0.8;indovina;Indovina]"
|
||||
}
|
||||
@ -143,10 +143,10 @@ Il metodo principale per farlo è usare `show_formspec`:
|
||||
|
||||
```lua
|
||||
function indovina.mostra_a(nome)
|
||||
minetest.show_formspec(nome, "indovina:gioco", indovina.prendi_formspec(nome))
|
||||
core.show_formspec(nome, "indovina:gioco", indovina.prendi_formspec(nome))
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("gioco", {
|
||||
core.register_chatcommand("gioco", {
|
||||
func = function(name)
|
||||
indovina.mostra_a(name)
|
||||
end,
|
||||
@ -180,19 +180,19 @@ Per far sì che i formspec siano utili, le informazioni devono essere ritornate
|
||||
Il metodo per fare ciò è chiamato Campo di Compilazione (*formspec field submission*), e per `show_formspec` quel campo viene ottenuto usando un callback globale:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
core.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if formname ~= "indovina:gioco" then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.indovina then
|
||||
local p_name = player:get_player_name()
|
||||
minetest.chat_send_all(p_name .. " ha tentato di indovinare con il numero " .. fields.numero)
|
||||
core.chat_send_all(p_name .. " ha tentato di indovinare con il numero " .. fields.numero)
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
La funzione data in `minetest.register_on_player_receive_fields` è chiamata ogni volta che un utente invia un modulo.
|
||||
La funzione data in `core.register_on_player_receive_fields` è chiamata ogni volta che un utente invia un modulo.
|
||||
La maggior parte dei callback necessiteranno di controllare il nome fornito alla funzione, e uscire se non è quello esatto; tuttavia, alcuni potrebbero necessitare di operare su più moduli, se non addirittura su tutti.
|
||||
|
||||
Il parametro `fields` è una tabella di tutti i valori inviati dall'utente, indicizzati per stringhe.
|
||||
@ -223,7 +223,7 @@ local function prendi_contesto(nome)
|
||||
return contesto
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
core.register_on_leaveplayer(function(player)
|
||||
_contexts[player:get_player_name()] = nil
|
||||
end)
|
||||
```
|
||||
@ -236,7 +236,7 @@ function indovina.mostra_a(nome)
|
||||
contesto.soluzione = contesto.soluzione or math.random(1, 10)
|
||||
|
||||
local formspec = indovina.prendi_formspec(nome, contesto)
|
||||
minetest.show_formspec(nome, "indovina:gioco", formspec)
|
||||
core.show_formspec(nome, "indovina:gioco", formspec)
|
||||
end
|
||||
```
|
||||
|
||||
@ -282,11 +282,11 @@ Ci sono tre diversi modi per far sì che un formspec sia consegnato al client:
|
||||
|
||||
### Formspec nei nodi
|
||||
|
||||
`minetest.show_formspec` non è l'unico modo per mostrare un formspec; essi possono infatti essere aggiunti anche ai [metadati di un nodo](../map/storage.html).
|
||||
`core.show_formspec` non è l'unico modo per mostrare un formspec; essi possono infatti essere aggiunti anche ai [metadati di un nodo](../map/storage.html).
|
||||
Per esempio, questo è usato con le casse per permettere tempi più veloci d'apertura - non si ha bisogno di aspettare che il server invii il formspec della cassa al giocatore.
|
||||
|
||||
```lua
|
||||
minetest.register_node("miamod:tastodestro", {
|
||||
core.register_node("miamod:tastodestro", {
|
||||
description = "Premimi col tasto destro del mouse!",
|
||||
tiles = {"miamod_tastodestro.png"},
|
||||
groups = {cracky = 1},
|
||||
@ -295,7 +295,7 @@ minetest.register_node("miamod:tastodestro", {
|
||||
-- Il codice che segue imposta il formspec della cassa.
|
||||
-- I metadati sono un modo per immagazzinare dati nel nodo.
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta = core.get_meta(pos)
|
||||
meta:set_string("formspec",
|
||||
"formspec_version[4]" ..
|
||||
"size[5,5]"..
|
||||
@ -312,7 +312,7 @@ minetest.register_node("miamod:tastodestro", {
|
||||
I formspec impostati in questo modo non innescano lo stesso callback.
|
||||
Per far in modo di ricevere il modulo di input per i formspec nei nodi, bisogna includere una voce `on_receive_fields` al registrare il nodo.
|
||||
|
||||
Questo stile di callback viene innescato al premere invio in un campo, che è possibile grazie a `minetest.show_formspec`; tuttavia, questi tipi di moduli possono essere mostrati solo
|
||||
Questo stile di callback viene innescato al premere invio in un campo, che è possibile grazie a `core.show_formspec`; tuttavia, questi tipi di moduli possono essere mostrati solo
|
||||
tramite il premere col tasto destro del mouse su un nodo. Non è possibile farlo programmaticamente.
|
||||
|
||||
### Inventario del giocatore
|
||||
|
@ -79,7 +79,7 @@ Questo permette all'intero pannello di essere ancorato sulla destra della finest
|
||||
Puoi creare un elemento HUD una volta ottenuto il riferimento al giocatore al quale assegnarla:
|
||||
|
||||
```lua
|
||||
local giocatore = minetest.get_player_by_name("tizio")
|
||||
local giocatore = core.get_player_by_name("tizio")
|
||||
local idx = giocatore:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = {x = 0.5, y = 0.5},
|
||||
@ -268,9 +268,9 @@ function punteggio.aggiorna_hud(giocatore)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(punteggio.aggiorna_hud)
|
||||
core.register_on_joinplayer(punteggio.aggiorna_hud)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
core.register_on_leaveplayer(function(player)
|
||||
hud_salvate[player:get_player_name()] = nil
|
||||
end)
|
||||
```
|
||||
|
@ -23,9 +23,9 @@ Per esempio, un valore di 2 sulla gravità, renderà la gravità di un utente du
|
||||
Segue l'esempio di un comando di antigravità:
|
||||
|
||||
```lua
|
||||
minetest.register_chatcommand("antigrav", {
|
||||
core.register_chatcommand("antigrav", {
|
||||
func = function(name, param)
|
||||
local giocatore = minetest.get_player_by_name(name)
|
||||
local giocatore = core.get_player_by_name(name)
|
||||
giocatore:set_physics_override({
|
||||
gravity = 0.1, -- imposta la gravità al 10% del suo valore originale
|
||||
-- (0.1 * 9.81)
|
||||
|
@ -46,7 +46,7 @@ I privilegi non sono fatti per indicare classi o status.
|
||||
Usa `register_privilege` per dichiarare un nuovo privilegio:
|
||||
|
||||
```lua
|
||||
minetest.register_privilege("voto", {
|
||||
core.register_privilege("voto", {
|
||||
description = "Può votare nei sondaggi",
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
@ -59,7 +59,7 @@ minetest.register_privilege("voto", {
|
||||
Per controllare velocemente se un giocatore ha tutti i privilegi necessari o meno:
|
||||
|
||||
```lua
|
||||
local celo, manca = minetest.check_player_privs(player_or_name, {
|
||||
local celo, manca = core.check_player_privs(player_or_name, {
|
||||
interact = true,
|
||||
voto = true })
|
||||
```
|
||||
@ -68,7 +68,7 @@ In quest'esempio, `celo` è true se il giocatore ha sia `interact` che `voto`.
|
||||
Se `celo` è false, allora `manca` conterrà una tabella con i privilegi mancanti.
|
||||
|
||||
```lua
|
||||
local celo, manca = minetest.check_player_privs(name, {
|
||||
local celo, manca = core.check_player_privs(name, {
|
||||
interact = true,
|
||||
voto = true })
|
||||
|
||||
@ -82,7 +82,7 @@ end
|
||||
Se non hai bisogno di controllare i privilegi mancanti, puoi inserire `check_player_privs` direttamente nel costrutto if:
|
||||
|
||||
```lua
|
||||
if not minetest.check_player_privs(name, { interact=true }) then
|
||||
if not core.check_player_privs(name, { interact=true }) then
|
||||
return false, "Hai bisogno del privilegio 'interact' per eseguire quest'azione!"
|
||||
end
|
||||
```
|
||||
@ -92,11 +92,11 @@ end
|
||||
Si può accedere o modificare i privilegi di un giocatore anche se quest'ultimo non risulta online.
|
||||
|
||||
```lua
|
||||
local privs = minetest.get_player_privs(name)
|
||||
local privs = core.get_player_privs(name)
|
||||
print(dump(privs))
|
||||
|
||||
privs.voto = true
|
||||
minetest.set_player_privs(name, privs)
|
||||
core.set_player_privs(name, privs)
|
||||
```
|
||||
|
||||
I privilegi sono sempre specificati come una tabella chiave-valore, con il loro nome come chiave e true/false come valore.
|
||||
|
@ -82,7 +82,7 @@ E hai ragione! L'API di Minetest è molto incentrata sull'Osservatore, per far i
|
||||
|
||||
## Modello-Vista-Controllo
|
||||
|
||||
Nel prossimo capitolo discuteremo di come testare automaticamente il codice, e uno dei problemi che riscontreremo sarà come separare il più possibile la logica (calcoli, cosa bisognerebbe fare) dalle chiamate alle API (`minetest.*`, altre mod).
|
||||
Nel prossimo capitolo discuteremo di come testare automaticamente il codice, e uno dei problemi che riscontreremo sarà come separare il più possibile la logica (calcoli, cosa bisognerebbe fare) dalle chiamate alle API (`core.*`, altre mod).
|
||||
|
||||
Un modo per fare ciò è pensare a:
|
||||
|
||||
@ -148,14 +148,14 @@ function terreno.mostra_formspec_crea(nome)
|
||||
]]
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("/land", {
|
||||
core.register_chatcommand("/land", {
|
||||
privs = { terreno = true },
|
||||
func = function(name)
|
||||
land.gestore_richiesta_crea(name)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
terreno.gestore_invio_crea(player:get_player_name(),
|
||||
fields.nome_area)
|
||||
@ -191,7 +191,7 @@ Al contrario, un approccio più comune e leggermente meno rigido è quello API-V
|
||||
In un mondo ideale, si avrebbero le 3 aree MVC perfettamente separate... ma siamo nel mondo reale.
|
||||
Un buon compromesso è ridurre la mod in due parti:
|
||||
|
||||
* **API** - modello + controllo. Non ci dovrebbe essere nessun uso di `minetest.` nella API.
|
||||
* **API** - modello + controllo. Non ci dovrebbe essere nessun uso di `core.` nella API.
|
||||
* **Vista** - la vista, esattamente come quella spiegata sopra.
|
||||
È buona norma strutturare questa parte in file separati per ogni tipo di evento.
|
||||
|
||||
|
@ -40,11 +40,11 @@ Per esempio, il seguente codice presenta una vulnerabilità che permette ai gioc
|
||||
|
||||
```lua
|
||||
local function show_formspec(name)
|
||||
if not minetest.check_player_privs(name, { privs = true }) then
|
||||
if not core.check_player_privs(name, { privs = true }) then
|
||||
return false
|
||||
end
|
||||
|
||||
minetest.show_formspec(name, "modman:modman", [[
|
||||
core.show_formspec(name, "modman:modman", [[
|
||||
size[3,2]
|
||||
field[0,0;3,1;target;Nome;]
|
||||
button_exit[0,1;3,1;sub;Promuovi]
|
||||
@ -52,14 +52,14 @@ local function show_formspec(name)
|
||||
return true
|
||||
})
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
-- MALE! Manca il controllo dei privilegi!
|
||||
|
||||
local privs = minetest.get_player_privs(fields.target)
|
||||
local privs = core.get_player_privs(fields.target)
|
||||
privs.kick = true
|
||||
privs.ban = true
|
||||
minetest.set_player_privs(fields.target, privs)
|
||||
core.set_player_privs(fields.target, privs)
|
||||
return true
|
||||
end)
|
||||
```
|
||||
@ -67,9 +67,9 @@ end)
|
||||
Aggiungi un controllo dei privilegi per ovviare:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
if not minetest.check_player_privs(name, { privs = true }) then
|
||||
if not core.check_player_privs(name, { privs = true }) then
|
||||
return false
|
||||
end
|
||||
|
||||
@ -105,7 +105,7 @@ inv:set_stack("main", 1, pila)
|
||||
Il comportamento dei callback è leggermente più complicato.
|
||||
|
||||
```lua
|
||||
minetest.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
core.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
itemstack, user, pointed_thing)
|
||||
itemstack:get_meta():set_string("description", "Un po' smangiucchiato")
|
||||
-- Quasi corretto! I dati saranno persi se un altro callback annulla questa chiamata
|
||||
@ -117,7 +117,7 @@ Se nessun callback cancella l'operazione, la pila sarà impostata e la descrizio
|
||||
È meglio quindi fare così:
|
||||
|
||||
```lua
|
||||
minetest.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
core.register_on_item_eat(function(hp_change, replace_with_item,
|
||||
itemstack, user, pointed_thing)
|
||||
itemstack:get_meta():set_string("description", "Un po' smangiucchiato")
|
||||
user:get_inventory():set_stack("main", user:get_wield_index(),
|
||||
|
@ -33,7 +33,7 @@ Qualsiasi utente può inviare qualsiasi formspec con i valori che preferisce qua
|
||||
Segue del codice trovato realmente in una mod:
|
||||
|
||||
```lua
|
||||
minetest.register_on_player_receive_fields(function(player,
|
||||
core.register_on_player_receive_fields(function(player,
|
||||
formname, fields)
|
||||
for key, field in pairs(fields) do
|
||||
local x,y,z = string.match(key,
|
||||
@ -71,7 +71,7 @@ Minetest permette alle mod di richiedere ambienti senza limiti, dando loro acces
|
||||
Riesci a individuare la vulnerabilità in questo pezzo di codice??
|
||||
|
||||
```lua
|
||||
local ie = minetest.request_insecure_environment()
|
||||
local ie = core.request_insecure_environment()
|
||||
ie.os.execute(("path/to/prog %d"):format(3))
|
||||
```
|
||||
|
||||
|
@ -42,12 +42,12 @@ Minetest ti permette di localizzare i tuoi contenuti in tante lingue diverse, ch
|
||||
### Testo formattato
|
||||
|
||||
Il server ha bisogno di dire ai client come tradurre il testo.
|
||||
Questo accade grazie alla funzione `minetest.get_translator(dominiotestuale)`, che abbrevieremo con `S()`:
|
||||
Questo accade grazie alla funzione `core.get_translator(dominiotestuale)`, che abbrevieremo con `S()`:
|
||||
|
||||
```lua
|
||||
local S = minetest.get_translator("miamod")
|
||||
local S = core.get_translator("miamod")
|
||||
|
||||
minetest.register_craftitem("miamod:oggetto", {
|
||||
core.register_craftitem("miamod:oggetto", {
|
||||
description = S("My Item"),
|
||||
})
|
||||
```
|
||||
@ -57,7 +57,7 @@ Piuttosto che avere tutte le traduzioni di una lingua salvate nello stesso file,
|
||||
È buona norma assegnare al dominio testuale lo stesso nome della mod, onde evitare conflitti tra mod diverse.
|
||||
|
||||
Il testo formattato può essere usato nella maggior parte dei casi dove è richiesto un testo fatto per gli esseri umani - come i formspec, i campi di definizioni di un oggetto, `infotext` ecc.
|
||||
Nel caso dei formspec, tieni presente che dovrai usare la funzione di escape `minetest.formspec_escape` per una corretta visualizzazione.
|
||||
Nel caso dei formspec, tieni presente che dovrai usare la funzione di escape `core.formspec_escape` per una corretta visualizzazione.
|
||||
|
||||
Quando il client incontra del testo formattato, come quello passato in `description`, ne andrà a cercare il corrispettivo nel file di traduzione della lingua del giocatore. Se la ricerca non avrà avuto esito positivo, ritornerà quello in inglese.
|
||||
|
||||
@ -95,8 +95,8 @@ Non è raro dover inserire una variabile dentro una stringa da tradurre.
|
||||
Al contrario, dovresti usare il seguente sistema di formattazione:
|
||||
|
||||
```lua
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
minetest.chat_send_all(S("Everyone, say hi to @1!", player:get_player_name()))
|
||||
core.register_on_joinplayer(function(player)
|
||||
core.chat_send_all(S("Everyone, say hi to @1!", player:get_player_name()))
|
||||
end)
|
||||
```
|
||||
|
||||
@ -130,13 +130,13 @@ local list = {
|
||||
S("Potato")
|
||||
}
|
||||
|
||||
minetest.register_chatcommand("find", {
|
||||
core.register_chatcommand("find", {
|
||||
func = function(name, param)
|
||||
local info = minetest.get_player_information(name)
|
||||
local info = core.get_player_information(name)
|
||||
local lingua = info and info.language or "en"
|
||||
|
||||
for _, riga in ipairs(lista) do
|
||||
local trad = minetest.get_translated_string(language, riga)
|
||||
local trad = core.get_translated_string(language, riga)
|
||||
if trad:contains(query) then
|
||||
return riga
|
||||
end
|
||||
|
@ -52,7 +52,7 @@ Quello che fa è cercare i file Lua con il nome che termina in `_spec`, eseguend
|
||||
```lua
|
||||
miamod = {}
|
||||
|
||||
dofile(minetest.get_modpath("miamod") .. "/api.lua")
|
||||
dofile(core.get_modpath("miamod") .. "/api.lua")
|
||||
```
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ _G.minetest = {}
|
||||
|
||||
-- Definisce la funzione simulata
|
||||
local chiamate_chat_send_all = {}
|
||||
function minetest.chat_send_all(name, message)
|
||||
function core.chat_send_all(name, message)
|
||||
table.insert(chiamate_chat_send_all, { nome = name, messaggio = message })
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user