Choose a language it

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 minetest.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 minetest.item_place
on_secondary_use clic destro a vuoto minetest.item_secondary_use (non fa nulla)
on_drop Q minetest.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:

minetest.register_craftitem("miamod:fangotorta", {
    description = "Torta aliena di fango",
    inventory_image = "miamod_fangotorta.png",
    on_use = minetest.item_eat(20),
})

Il numero fornito alla funzione minetest.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. Ciò significa che il codice in alto è alquanto simile al seguente:

minetest.register_craftitem("miamod:fangotorta", {
    description = "Torta aliena di fango",
    inventory_image = "miamod_fangotorta.png",
    on_use = function(...)
        return minetest.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 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_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.

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 minetest.item_place e minetest.node_dig. Alcune sono usate direttamente, mentre altre sono funzioni che ritornano il richiamo vero e proprio:

minetest.register_item("miamod:esempio", {
    on_place = minetest.item_place,
    on_use = minetest.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).

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 minetest.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.

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.

minetest.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!")
        end
    end,
    on_construct = function(pos, node)
        local meta = minetest.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)
            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 minetest.node_dig, che controlla eventuali protezioni dell’area, usura l’oggetto, rimuove il nodo, e ne esegue il richiamo after_dig_node.

minetest.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!")
        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.