Richiami dei nodi e degli oggetti
Introduction
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 core.register_on_punchnode
, che in questo caso verrà invocato al colpire qualsiasi nodo.
Richiami degli oggetti
Quando un giocatore ha un nodo, un oggetto fabbricabile o uno strumento nel proprio inventario, questi potrebbero innescare degli eventi:
Richiamo | Assegnazione base | Valore base |
---|---|---|
on_use | clic sinistro | nil |
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 |
on_use
Sovrascrivere l’uso dell’oggetto impedisce che quest’ultimo possa essere usato per scavare nodi. Un impiego comune di questo richiamo lo si trova nel cibo:
core.register_craftitem("miamod:fangotorta", {
description = "Torta aliena di fango",
inventory_image = "miamod_fangotorta.png",
on_use = core.item_eat(20),
})
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.
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:
core.register_craftitem("miamod:fangotorta", {
description = "Torta aliena di fango",
inventory_image = "miamod_fangotorta.png",
on_use = function(...)
return core.do_item_eat(20, nil, ...)
end,
})
Capendo come funziona item_eat, è possibile modificarlo per operazioni più complesse come per esempio riprodurre un suono personalizzato.
on_place e on_secondary_use
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 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 core.item_drop
, la quale gestisce il buttare l’oggetto.
after_use
after_use
viene chiamato quando si scava un nodo, e permette di personalizzare come viene applicata l’usura a uno strumento. Se after_use
non esiste, è come se ci fosse scritto:
after_use = function(itemstack, user, node, digparams)
itemstack:add_wear(digparams.wear)
return itemstack
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 core.item_place
e core.node_dig
. Alcune sono usate direttamente, mentre altre sono funzioni che ritornano il richiamo vero e proprio:
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 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
Quando un nodo si trova in un inventario, vengono invocati i richiami degli oggetti discussi poc’anzi. Al contrario, quando un nodo è situato nel mondo, vengono invocati i richiami dei nodi. Ce ne sono di svariati tipi, troppi per essere discussi in questo libro, tuttavia alcuni di questi verranno trattati nei capitoli successivi.
Molti richiami dei nodi sono collegati alle operazioni effettuate - appunto - sui nodi, come piazzarli e rimuoverli dal mondo. È importante però sottolineare che, per motivi di prestazioni, operazioni come queste non vengono chiamate da modifiche in blocco (quelle che cambiano un grande numero di nodi in un colpo solo). È meglio quindi non fare affidamento su un’esecuzione sicura al 100%.
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 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, 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.
È importante notare che i giocatori non sono le uniche realtà che possono piazzare nodi; anche le entità e le mod possono farlo. Per via di ciò, place
potrebbe essere un giocatore, ma anche un’entità o nil
.
core.register_node("miamod:mionodo", {
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if clicker:is_player() then
core.chat_send_player(clicker:get_player_name(), "Ciao mondo!")
end
end,
on_construct = function(pos, node)
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 = core.get_meta(pos)
meta:set_string("proprietario", placer:get_player_name())
end
end,
})
Colpire e scavare
Si ha un colpo quando un giocatore preme col tasto sinistro per un breve periodo. 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 core.node_dig
, che controlla eventuali protezioni dell’area, usura l’oggetto, rimuove il nodo, e ne esegue il richiamo after_dig_node
.
core.register_node("miamod:mionodo", {
on_punch = function(pos, node, puncher, pointed_thing)
if puncher:is_player() then
core.chat_send_player(puncher:get_player_name(), "Ahia!")
end
end,
})
…e altro!
Dài un occhio alla API Lua di Minetest per una lista di tutti i richiami, e per avere più informazioni riguardo quelli vista qui sopra.