Choose a language it

Chat e comandi

Introduzione

Le mod possono interagire con la chat del giocatore, tra l’inviare messaggi, intercettarli e registrare dei comandi.

Inviare messaggi

A tutti i giocatori

Per inviare un messaggio a tutti i giocatori connessi in gioco, si usa la funzione chat_send_all:

minetest.chat_send_all("Questo è un messaggio visualizzabile da tutti")

Segue un esempio di come apparirerebbe in gioco:

<Tizio> Guarda qui
Questo è un messaggio visualizzabile da tutti
<Caio> Eh, cosa?

Il messaggio appare su una nuova riga, per distinguerlo dai messaggi dei giocatori.

A giocatori specifici

Per inviare un messaggio a un giocatore in particolare, si usa invece la funzione chat_send_player:

minetest.chat_send_player("Tizio", "Questo è un messaggio per Tizio")

Questo messaggio viene mostrato esattamente come il precedente, ma solo, in questo caso, a Tizio.

Comandi

Per registrare un comando, per esempio /foo, si usa register_chatcommand:

minetest.register_chatcommand("foo", {
    privs = {
        interact = true,
    },
    func = function(name, param)
        return true, "Hai detto " .. param .. "!"
    end,
})

Nel codice qui in alto, interact è elencato come privilegio necessario; in altre parole, solo i giocatori che hanno quel privilegio possono usare il comando.

param è una stringa contenente tutto ciò che un giocatore scrive dopo il nome del comando. Per esempio, in /grantme uno,due,tre, param equivarrà a uno,due,tre.

I comandi ritornano un massimo di due valori, dove il primo è un booleano che indica l’eventuale successo, mentre il secondo è un messaggio da inviare all’utente.

I giocatori offline possono eseguire comandi

Viene passato il nome del giocatore al posto del giocatore in sé perché le mod possono eseguire comandi in vece di un giocatore offline. 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.

Accettare più argomenti

Non è raro che i comandi richiedano più argomenti, come per esempio /squadra entra <nome_squadra>. Ci sono due modi per implementare ciò: usare string.split o i pattern Lua.

Usare string.split

Una stringa può essere spezzettata in più parti tramite string.split(" "):

local parti = param:split(" ")
local cmd = parti[1]

if cmd == "entra" then
    local nome_squadra = parti[2]
    squadra.entra(name, nome_squadra)
    return true, "Sei dentro la squadra!"
elseif cmd == "gioc_max" then
    local nome_squadra = parti[2]
    local gioc_max = tonumber(parti[3])
    if nome_squadra and gioc_max then
        return true, "Giocatori massimi della squadra " .. nome_squadra .. " impostati a " .. gioc_max
    else
        return false, "Uso: /squadra gioc_max <nome_squadra> <numero>"
    end
else
    return false, "È necessario un comando"
end

Usare i pattern Lua

I pattern Lua sono un modo per estrapolare pezzi di testo seguendo delle regole. Sono perfetti in caso di argomenti che contengono spazi, o comunque quando è richiesto un controllo più meticoloso dei parametri catturati.

local a, msg = string.match(param, "^([%a%d_-]+) (.+)$")

Il codice sovrastante implementa /msg <a> <messaggio>. Vediamo cos’è successo partendo da sinistra:

  • ^ dice di iniziare a combaciare dall’inizio della stringa;
  • () è un gruppo - qualsiasi cosa che combaci con ciò che è contenuto al suo interno verrà ritornato da string.match;
  • [] significa che i caratteri al suo interno sono accettati;
  • %a significa che accetta ogni lettera e %d ogni cifra.
  • [%a%d_-] significa che accetta ogni lettera, cifra, _ e -.
  • + dice di combaciare ciò che lo precede una o più volte.
  • . dice di combaciare qualsiasi tipo di carattere.
  • $ dice di combaciare la fine della stringa.

Detto semplicemente, il pattern cerca un nome (una parola fatta di lettere, numeri, trattini o trattini bassi), poi uno spazio e poi il messaggio (uno o più caratteri, qualsiasi essi siano). Vengono poi ritornati nome e messaggio, perché sono inseriti nelle parentesi.

Questo è come molte mod implementano comandi complessi. Una guida più completa ai pattern è probabilmente quella su lua-users.org o la documentazione PIL.

C'è anche una libreria scritta dall'autore di questo libro che può essere usata per creare comandi complessi senza l'utilizzo di pattern: Chat Command Builder.

Intercettare i messaggi

Per intercettare un messaggio, si usa register_on_chat_message:

minetest.register_on_chat_message(function(name, message)
    print(name .. " ha detto " .. message)
    return false
end)

Ritornando false, si permette al messaggio di essere inviato. In verità return false può anche essere omesso in quanto nil verrebbe ritornato implicitamente, e nil è trattato come false.

Privilegi e comandi

Il privilegio shout non è necessario per far sì che un giocatore attivi questo richiamo. Questo perché i comandi sono implementati in Lua, e sono semplicemente dei messaggi in chat che iniziano con /.

Dovresti assicurarti, poi, che il messaggio potrebbe essere un comando che invia messaggi in chat, o che l’utente potrebbere non avere shout.

minetest.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
        print(name .. " ha detto " .. message)
    else
        print(name .. " ha provato a dire " .. message ..
                " ma non ha lo shout")
    end

    return false
end)