master #2

Merged
BRNSystems merged 9 commits from Mirrorlandia_minetest/minetest:master into master 2023-11-29 10:49:42 +01:00
13 changed files with 281 additions and 207 deletions

@ -81,7 +81,7 @@ task prepareAssets() {
from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts" from "${projRoot}/fonts" include "*.ttf" into "${assetsFolder}/fonts"
} }
copy { copy {
from "${projRoot}/textures" into "${assetsFolder}/textures" from "${projRoot}/textures/base/pack" into "${assetsFolder}/textures/base/pack"
} }
// compile translations // compile translations

@ -207,7 +207,7 @@ Available commands: (see also: /help <cmd>)=Verfügbare Befehle: (siehe auch: /h
Close=Schließen Close=Schließen
Privilege=Privileg Privilege=Privileg
Description=Beschreibung Description=Beschreibung
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<Filter>] | dump [<Filter>] | save [<Format> [<Filter>]] print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<Filter>] | dump [<Filter>] | save [<Format> [<Filter>]] | reset
Handle the profiler and profiling data=Den Profiler und Profilingdaten verwalten Handle the profiler and profiling data=Den Profiler und Profilingdaten verwalten
Statistics written to action log.=Statistiken zum Aktionsprotokoll geschrieben. Statistics written to action log.=Statistiken zum Aktionsprotokoll geschrieben.
Statistics were reset.=Statistiken wurden zurückgesetzt. Statistics were reset.=Statistiken wurden zurückgesetzt.

@ -2,8 +2,8 @@
Empty command.=Perintah kosong. Empty command.=Perintah kosong.
Invalid command: @1=Perintah tidak sah: @1 Invalid command: @1=Perintah tidak sah: @1
Invalid command usage.=Penggunaan perintah tidak sah. Invalid command usage.=Penggunaan perintah tidak sah.
(@1 s)= (@1 detik) (@1 s)= (@1 detik)
Command execution took @1 s=Pelaksanaan perintah memerlukan @1 detik Command execution took @1 s=Pelaksanaan perintah memerlukan @1 detik
You don't have permission to run this command (missing privileges: @1).=Anda tidak memiliki izin untuk menjalankan perintah ini (hak tidak ada: @1). You don't have permission to run this command (missing privileges: @1).=Anda tidak memiliki izin untuk menjalankan perintah ini (hak tidak ada: @1).
Unable to get position of player @1.=Tidak dapat mengambil letak pemain @1. Unable to get position of player @1.=Tidak dapat mengambil letak pemain @1.
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Format daerah tidak sah. Diharapkan: (x1,y1,z1) (x2,y2,z2) Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Format daerah tidak sah. Diharapkan: (x1,y1,z1) (x2,y2,z2)

@ -1,78 +1,79 @@
# textdomain: __builtin # textdomain: __builtin
# note for transaltors: sono state seguite le norme di https://italianoinclusivo.it/ a parte per il suffisso -tore -trice, con l'intento di trasformarlo in un epiceno
Empty command.=Comando vuoto. Empty command.=Comando vuoto.
Invalid command: @1=Comando non valido: @1 Invalid command: @1=Comando non valido: @1
Invalid command usage.=Utilizzo del comando non valido. Invalid command usage.=Utilizzo del comando non valido.
(@1 s)= (@1 s)= (@1 s)
Command execution took @1 s= Command execution took @1 s=L'esecuzione del comando ha richiesto @1 s
You don't have permission to run this command (missing privileges: @1).=Non hai il permesso di eseguire questo comando (privilegi mancanti: @1). You don't have permission to run this command (missing privileges: @1).=Non hai il permesso di eseguire questo comando (privilegi mancanti: @1).
Unable to get position of player @1.=Impossibile ottenere la posizione del giocatore @1. Unable to get position of player @1.=Impossibile ottenere la posizione del giocatore @1.
Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Formato dell'area non corretto. Richiesto: (x1,y1,z1) (x2,y2,z2) Incorrect area format. Expected: (x1,y1,z1) (x2,y2,z2)=Formato dell'area non corretto. Richiesto: (x1,y1,z1) (x2,y2,z2)
<action>=<azione> <action>=<azione>
Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Mostra un'azione in chat (es. `/me ordina una pizza` mostra `<nome giocatore> ordina una pizza`) Show chat action (e.g., '/me orders a pizza' displays '<player name> orders a pizza')=Mostra un'azione in chat (es. `/me ordina una pizza` mostra `<nome giocatore> ordina una pizza`)
Show the name of the server owner=Mostra il nome del proprietario del server Show the name of the server owner=Mostra il nome di chi possiede il server
The administrator of this server is @1.=L'amministratore di questo server è @1. The administrator of this server is @1.=L'amministratore di questo server è @1.
There's no administrator named in the config file.=Non c'è nessun amministratore nel file di configurazione. There's no administrator named in the config file.=Non c'è nessun*amministratore nel file di configurazione.
@1 does not have any privileges.= @1 does not have any privileges.=@1 non ha nessun privilegio
Privileges of @1: @2=Privilegi di @1: @2 Privileges of @1: @2=Privilegi di @1: @2
[<name>]=[<nome>] [<name>]=[<nome>]
Show privileges of yourself or another player=Mostra i privilegi propri o di un altro giocatore Show privileges of yourself or another player=Mostra i privilegi propri o di un*altrə giocatore
Player @1 does not exist.=Il giocatore @1 non esiste. Player @1 does not exist.= giocatore @1 non esiste.
<privilege>=<privilegio> <privilege>=<privilegio>
Return list of all online players with privilege=Ritorna una lista di tutti i giocatori connessi col tale privilegio Return list of all online players with privilege=Ritorna una lista di tuttɜ lɜ giocatori connessɜ col tale privilegio
Invalid parameters (see /help haspriv).=Parametri non validi (vedi /help haspriv). Invalid parameters (see /help haspriv).=Parametri non validi (vedi /help haspriv).
Unknown privilege!=Privilegio sconosciuto! Unknown privilege!=Privilegio sconosciuto!
No online player has the "@1" privilege.= No online player has the "@1" privilege.=Nessunə giocatore ha il privilegio "@1".
Players online with the "@1" privilege: @2=Giocatori connessi con il privilegio "@1": @2 Players online with the "@1" privilege: @2=Giocatori connessɜ con il privilegio "@1": @2
Your privileges are insufficient.=I tuoi privilegi sono insufficienti. Your privileges are insufficient.=I tuoi privilegi sono insufficienti.
Your privileges are insufficient. '@1' only allows you to grant: @2= Your privileges are insufficient. '@1' only allows you to grant: @2=I tuoi privilegi sono insufficienti. '@1' ti permette soltanto di elargire: @2
Unknown privilege: @1=Privilegio sconosciuto: @1 Unknown privilege: @1=Privilegio sconosciuto: @1
@1 granted you privileges: @2=@1 ti ha assegnato i seguenti privilegi: @2 @1 granted you privileges: @2=@1 ti ha assegnato i seguenti privilegi: @2
<name> (<privilege> [, <privilege2> [<...>]] | all)= <name> (<privilege> [, <privilege2> [<...>]] | all)=<nome> (<privilegio> [, <privilegio2> [<...>]] | all)
Give privileges to player=Dà privilegi al giocatore Give privileges to player=Dà privilegi al giocatore
Invalid parameters (see /help grant).=Parametri non validi (vedi /help grant). Invalid parameters (see /help grant).=Parametri non validi (vedi /help grant).
<privilege> [, <privilege2> [<...>]] | all= <privilege> [, <privilege2> [<...>]] | all=<privilegio> [, <privilegio2> [<...>]] | all
Grant privileges to yourself=Assegna dei privilegi a te stessǝ Grant privileges to yourself=Assegna dei privilegi a te stessǝ
Invalid parameters (see /help grantme).=Parametri non validi (vedi /help grantme). Invalid parameters (see /help grantme).=Parametri non validi (vedi /help grantme).
Your privileges are insufficient. '@1' only allows you to revoke: @2= Your privileges are insufficient. '@1' only allows you to revoke: @2=I tuoi privilegi sono insufficienti. '@1' ti permette soltanto di revocare: @2
Note: Cannot revoke in singleplayer: @1= Note: Cannot revoke in singleplayer: @1=N.B.: Non si può revocare in locale: @1
Note: Cannot revoke from admin: @1= Note: Cannot revoke from admin: @1=N.B.: Non si può revocare a un*amministratore: @1
No privileges were revoked.= No privileges were revoked.=Nessun privilegio è stato revocato.
@1 revoked privileges from you: @2=@1 ti ha revocato i seguenti privilegi: @2 @1 revoked privileges from you: @2=@1 ti ha revocato i seguenti privilegi: @2
Remove privileges from player=Rimuove privilegi dal giocatore Remove privileges from player=Rimuove privilegi dal giocatore
Invalid parameters (see /help revoke).=Parametri non validi (vedi /help revoke). Invalid parameters (see /help revoke).=Parametri non validi (vedi /help revoke).
Revoke privileges from yourself=Revoca privilegi a te stessǝ Revoke privileges from yourself=Revoca privilegi a te stessǝ
Invalid parameters (see /help revokeme).=Parametri non validi (vedi /help revokeme). Invalid parameters (see /help revokeme).=Parametri non validi (vedi /help revokeme).
<name> <password>=<nome> <password> <name> <password>=<nome> <password>
Set player's password (sent unencrypted, thus insecure)= Set player's password (sent unencrypted, thus insecure)=Imposta la password dellə giocatore (non crittografata, ergo insicura)
Name field required.=Campo "nome" richiesto. Name field required.=Campo "nome" richiesto.
Your password was cleared by @1.=La tua password è stata resettata da @1. Your password was cleared by @1.=La tua password è stata resettata da @1.
Password of player "@1" cleared.=Password del giocatore "@1" resettata. Password of player "@1" cleared.=Password del giocatore "@1" resettata.
Your password was set by @1.=La tua password è stata impostata da @1. Your password was set by @1.=La tua password è stata impostata da @1.
Password of player "@1" set.=Password del giocatore "@1" impostata. Password of player "@1" set.=Password del giocatore "@1" impostata.
<name>=<nome> <name>=<nome>
Set empty password for a player=Imposta una password vuota a un giocatore Set empty password for a player=Imposta una password vuota a un giocatore
Reload authentication data=Ricarica i dati d'autenticazione Reload authentication data=Ricarica i dati d'autenticazione
Done.=Fatto. Done.=Fatto.
Failed.=Errore. Failed.=Errore.
Remove a player's data=Rimuove i dati di un giocatore Remove a player's data=Rimuove i dati di unə giocatore
Player "@1" removed.=Giocatore "@1" rimosso. Player "@1" removed.=Giocatore "@1" rimosso.
No such player "@1" to remove.=Non è presente nessun giocatore "@1" da rimuovere. No such player "@1" to remove.=Non è presente nessunə giocatore "@1" da rimuovere.
Player "@1" is connected, cannot remove.=Il giocatore "@1" è connesso, non può essere rimosso. Player "@1" is connected, cannot remove.=Lə giocatore "@1" è connessə, non può essere rimossə.
Unhandled remove_player return code @1.=Codice ritornato da remove_player non gestito (@1). Unhandled remove_player return code @1.=Codice ritornato da remove_player non gestito (@1).
Cannot teleport out of map bounds!=Non ci si può teletrasportare fuori dai limiti della mappa! Cannot teleport out of map bounds!=Non ci si può teletrasportare fuori dai limiti della mappa!
Cannot get player with name @1.=Impossibile trovare il giocatore chiamato @1. Cannot get player with name @1.=Impossibile trovare lə giocatore chiamato @1.
Cannot teleport, @1 is attached to an object!=Impossibile teletrasportare, @1 è attaccato a un oggetto! Cannot teleport, @1 is attached to an object!=Impossibile teletrasportare, @1 è attaccatə a un oggetto!
Teleporting @1 to @2.=Teletrasportando @1 da @2. Teleporting @1 to @2.=Teletrasportando @1 da @2.
One does not teleport to oneself.=Non ci si può teletrasportare su se stessi. One does not teleport to oneself.=Non ci si può teletrasportare su se stessɜ.
Cannot get teleportee with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto Cannot get teleportee with name @1.=Impossibile trovare lə giocatore chiamatə @1 per il teletrasporto
Cannot get target player with name @1.=Impossibile trovare il giocatore chiamato @1 per il teletrasporto Cannot get target player with name @1.=Impossibile trovare lə giocatore chiamato @1 per il teletrasporto
Teleporting @1 to @2 at @3.=Teletrasportando @1 da @2 a @3 Teleporting @1 to @2 at @3.=Teletrasportando @1 da @2 a @3
<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <da_nome> | <nome> <X>,<Y>,<Z> | <nome> <da_nome> <X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>=<X>,<Y>,<Z> | <da_nome> | <nome> <X>,<Y>,<Z> | <nome> <da_nome>
Teleport to position or player=Teletrasporta a una posizione o da un giocatore Teleport to position or player=Teletrasporta a una posizione o da unə giocatore
You don't have permission to teleport other players (missing privilege: @1).=Non hai il permesso di teletrasportare altri giocatori (privilegio mancante: @1). You don't have permission to teleport other players (missing privilege: @1).=Non hai il permesso di teletrasportare altrɜ giocatori (privilegio mancante: @1).
([-n] <name> <value>) | <name>=([-n] <nome> <valore>) | <nome> ([-n] <name> <value>) | <name>=([-n] <nome> <valore>) | <nome>
Set or read server configuration setting=Imposta o ottieni le configurazioni del server Set or read server configuration setting=Imposta o ottieni le configurazioni del server
Failed. Cannot modify secure settings. Edit the settings file manually.= Failed. Cannot modify secure settings. Edit the settings file manually.=Errore. Non è possibile modificare le impostazioni di sicurezza. Modifica manualmente il file d'impostazioni.
Failed. Use '/set -n <name> <value>' to create a new setting.=Errore. Usa 'set -n <nome> <valore>' per creare una nuova impostazione Failed. Use '/set -n <name> <value>' to create a new setting.=Errore. Usa 'set -n <nome> <valore>' per creare una nuova impostazione
@1 @= @2=@1 @= @2 @1 @= @2=@1 @= @2
<not set>=<non impostato> <not set>=<non impostato>
@ -89,11 +90,11 @@ Resets lighting in the area between pos1 and pos2 (<pos1> and <pos2> must be in
Successfully reset light in the area ranging from @1 to @2.=Luce nell'area tra @1 e @2 reimpostata con successo. Successfully reset light in the area ranging from @1 to @2.=Luce nell'area tra @1 e @2 reimpostata con successo.
Failed to load one or more blocks in area.=Errore nel caricare uno o più blocchi mappa nell'area. Failed to load one or more blocks in area.=Errore nel caricare uno o più blocchi mappa nell'area.
List mods installed on the server=Elenca le mod installate nel server List mods installed on the server=Elenca le mod installate nel server
No mods installed.= No mods installed.=Nessuna mod installata.
Cannot give an empty item.=Impossibile dare un oggetto vuoto. Cannot give an empty item.=Impossibile dare un oggetto vuoto.
Cannot give an unknown item.=Impossibile dare un oggetto sconosciuto. Cannot give an unknown item.=Impossibile dare un oggetto sconosciuto.
Giving 'ignore' is not allowed.=Non è permesso dare 'ignore'. Giving 'ignore' is not allowed.=Non è permesso dare 'ignore'.
@1 is not a known player.=@1 non è un giocatore conosciuto. @1 is not a known player.=@1 non è unə giocatore conosciutə.
@1 partially added to inventory.=@1 parzialmente aggiunto all'inventario. @1 partially added to inventory.=@1 parzialmente aggiunto all'inventario.
@1 could not be added to inventory.=@1 non può essere aggiunto all'inventario. @1 could not be added to inventory.=@1 non può essere aggiunto all'inventario.
@1 added to inventory.=@1 aggiunto all'inventario. @1 added to inventory.=@1 aggiunto all'inventario.
@ -101,7 +102,7 @@ Giving 'ignore' is not allowed.=Non è permesso dare 'ignore'.
@1 could not be added to inventory of @2.=Non è stato possibile aggiungere @1 all'inventario di @2. @1 could not be added to inventory of @2.=Non è stato possibile aggiungere @1 all'inventario di @2.
@1 added to inventory of @2.=@1 aggiunto all'inventario di @2. @1 added to inventory of @2.=@1 aggiunto all'inventario di @2.
<name> <ItemString> [<count> [<wear>]]=<nome> <NomeOggetto> [<quantità> [<usura>]] <name> <ItemString> [<count> [<wear>]]=<nome> <NomeOggetto> [<quantità> [<usura>]]
Give item to player=Dà oggetti ai giocatori Give item to player=Dà oggetti allɜ giocatori
Name and ItemString required.=Richiesti nome e NomeOggetto. Name and ItemString required.=Richiesti nome e NomeOggetto.
<ItemString> [<count> [<wear>]]=<NomeOggetto> [<quantità> [<usura>]] <ItemString> [<count> [<wear>]]=<NomeOggetto> [<quantità> [<usura>]]
Give item to yourself=Dà oggetti a te stessǝ Give item to yourself=Dà oggetti a te stessǝ
@ -109,29 +110,29 @@ ItemString required.=Richiesto NomeOggetto.
<EntityName> [<X>,<Y>,<Z>]=<NomeEntità> [<X>,<Y>,<Z>] <EntityName> [<X>,<Y>,<Z>]=<NomeEntità> [<X>,<Y>,<Z>]
Spawn entity at given (or your) position=Genera un'entità alla data coordinata (o la tua) Spawn entity at given (or your) position=Genera un'entità alla data coordinata (o la tua)
EntityName required.=Richiesto NomeEntità EntityName required.=Richiesto NomeEntità
Unable to spawn entity, player is nil.=Impossibile generare l'entità, il giocatore è nil. Unable to spawn entity, player is nil.=Impossibile generare l'entità, lə giocatore è nil.
Cannot spawn an unknown entity.=Impossibile generare un'entità sconosciuta. Cannot spawn an unknown entity.=Impossibile generare un'entità sconosciuta.
Invalid parameters (@1).=Parametri non validi (@1). Invalid parameters (@1).=Parametri non validi (@1).
@1 spawned.=Generata entità @1. @1 spawned.=Generata entità @1.
@1 failed to spawn.=Errore nel generare @1 @1 failed to spawn.=Errore nel generare @1
Destroy item in hand=Distrugge l'oggetto in mano Destroy item in hand=Distrugge l'oggetto in mano
Unable to pulverize, no player.=Impossibile polverizzare, nessun giocatore. Unable to pulverize, no player.=Impossibile polverizzare, nessunə giocatore.
Unable to pulverize, no item in hand.=Impossibile polverizzare, nessun oggetto in mano. Unable to pulverize, no item in hand.=Impossibile polverizzare, nessun oggetto in mano.
An item was pulverized.=Un oggetto è stato polverizzato. An item was pulverized.=Un oggetto è stato polverizzato.
[<range>] [<seconds>] [<limit>]=[<raggio>] [<secondi>] [<limite>] [<range>] [<seconds>] [<limit>]=[<raggio>] [<secondi>] [<limite>]
Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Controlla chi è l'ultimo giocatore che ha toccato un nodo o un nodo nelle sue vicinanze, negli ultimi secondi indicati. Di base: raggio @= 0, secondi @= 86400 @= 24h, limite @= 5. Check who last touched a node or a node near it within the time specified by <seconds>. Default: range @= 0, seconds @= 86400 @= 24h, limit @= 5. Set <seconds> to inf for no time limit=Controlla chi è l'ultimə giocatore che ha toccato un nodo o un nodo nelle sue vicinanze, negli ultimi secondi indicati. Di base: raggio @= 0, secondi @= 86400 @= 24h, limite @= 5.
Rollback functions are disabled.=Le funzioni di rollback sono disabilitate. Rollback functions are disabled.=Le funzioni di rollback sono disabilitate.
That limit is too high!=Il limite è troppo alto! That limit is too high!=Il limite è troppo alto!
Checking @1 ...=Controllando @1 ... Checking @1 ...=Controllando @1 ...
Nobody has touched the specified location in @1 seconds.=Nessuno ha toccato il punto specificato negli ultimi @1 secondi. Nobody has touched the specified location in @1 seconds.=Nessunə ha toccato il punto specificato negli ultimi @1 secondi.
@1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 @5 secondi fa. @1 @2 @3 -> @4 @5 seconds ago.=@1 @2 @3 -> @4 @5 secondi fa.
Punch a node (range@=@1, seconds@=@2, limit@=@3).=Colpisce un nodo (raggio@=@1, secondi@=@2, limite@=@3) Punch a node (range@=@1, seconds@=@2, limit@=@3).=Colpisce un nodo (raggio@=@1, secondi@=@2, limite@=@3)
(<name> [<seconds>]) | (:<actor> [<seconds>])=(<nome> [<secondi>]) | (:<attore> [<secondi>]) (<name> [<seconds>]) | (:<actor> [<seconds>])=(<nome> [<secondi>]) | (:<attore> [<secondi>])
Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Riavvolge le azioni di un giocatore. Di base, <secondi> è 60. Imposta <secondi> a inf per nessun limite di tempo Revert actions of a player. Default for <seconds> is 60. Set <seconds> to inf for no time limit=Riavvolge le azioni di unə giocatore. Di base, <secondi> è 60. Imposta <secondi> a inf per nessun limite di tempo
Invalid parameters. See /help rollback and /help rollback_check.=Parametri non validi. Vedi /help rollback e /help rollback_check. Invalid parameters. See /help rollback and /help rollback_check.=Parametri non validi. Vedi /help rollback e /help rollback_check.
Reverting actions of player '@1' since @2 seconds.=Riavvolge le azioni del giocatore '@1' avvenute negli ultimi @2 secondi. Reverting actions of player '@1' since @2 seconds.=Riavvolge le azioni del giocatore '@1' avvenute negli ultimi @2 secondi.
Reverting actions of @1 since @2 seconds.=Riavvolge le azioni di @1 avvenute negli ultimi @2 secondi. Reverting actions of @1 since @2 seconds.=Riavvolge le azioni di @1 avvenute negli ultimi @2 secondi.
(log is too long to show)=(il log è troppo lungo per essere mostrato) (log is too long to show)=(lo storico è troppo lungo per essere mostrato)
Reverting actions succeeded.=Riavvolgimento azioni avvenuto con successo. Reverting actions succeeded.=Riavvolgimento azioni avvenuto con successo.
Reverting actions FAILED.=Errore nel riavvolgere le azioni. Reverting actions FAILED.=Errore nel riavvolgere le azioni.
Show server status=Mostra lo stato del server Show server status=Mostra lo stato del server
@ -140,68 +141,68 @@ This command was disabled by a mod or game.=Questo comando è stato disabilitato
Show or set time of day=Mostra o imposta l'orario della giornata Show or set time of day=Mostra o imposta l'orario della giornata
Current time is @1:@2.=Orario corrente: @1:@2. Current time is @1:@2.=Orario corrente: @1:@2.
You don't have permission to run this command (missing privilege: @1).=Non hai il permesso di eseguire questo comando (privilegio mancante: @1) You don't have permission to run this command (missing privilege: @1).=Non hai il permesso di eseguire questo comando (privilegio mancante: @1)
Invalid time (must be between 0 and 24000).= Invalid time (must be between 0 and 24000).=Orario non valido (deve essere tra 0 e 24000).
Time of day changed.=Orario della giornata cambiato. Time of day changed.=Orario della giornata cambiato.
Invalid hour (must be between 0 and 23 inclusive).=Ora non valida (deve essere tra 0 e 23 inclusi) Invalid hour (must be between 0 and 23 inclusive).=Ora non valida (deve essere tra 0 e 23 inclusi)
Invalid minute (must be between 0 and 59 inclusive).=Minuto non valido (deve essere tra 0 e 59 inclusi) Invalid minute (must be between 0 and 59 inclusive).=Minuto non valido (deve essere tra 0 e 59 inclusi)
Show day count since world creation=Mostra il conteggio dei giorni da quando il mondo è stato creato Show day count since world creation=Mostra il conteggio dei giorni da quando il mondo è stato creato
Current day is @1.=Giorno attuale: @1. Current day is @1.=Giorno attuale: @1.
[<delay_in_seconds> | -1] [-r] [<message>]= [<delay_in_seconds> | -1] [-r] [<message>]=[<ritardo_in_secondi> | -1] [-r] [<messaggio>]
Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)= Shutdown server (-1 cancels a delayed shutdown, -r allows players to reconnect)=Arresta il server (-1 cancella un arresto programmato, -r permette allɜ giocatori di riconnettersi)
Server shutting down (operator request).=Arresto del server in corso (per richiesta dell'operatore) Server shutting down (operator request).=Arresto del server in corso (per richiesta dell'operatore)
Ban the IP of a player or show the ban list=Bandisce l'IP del giocatore o mostra la lista di quelli banditi Ban the IP of a player or show the ban list=Bandisce l'IP dellə giocatore o mostra la lista di quellɜ banditɜ
The ban list is empty.=La lista banditi è vuota. The ban list is empty.=La lista banditɜ è vuota.
Ban list: @1=Lista banditi: @1 Ban list: @1=Lista banditɜ: @1
You cannot ban players in singleplayer!= You cannot ban players in singleplayer!=Non puoi bandire giocatori in locale!
Player is not online.=Il giocatore non è connesso. Player is not online.=Lə giocatore non è connessə.
Failed to ban player.=Errore nel bandire il giocatore. Failed to ban player.=Errore nel bandire lə giocatore.
Banned @1.=@1 banditǝ. Banned @1.=@1 banditǝ.
<name> | <IP_address>=<nome> | <indirizzo_IP> <name> | <IP_address>=<nome> | <indirizzo_IP>
Remove IP ban belonging to a player/IP=Perdona l'IP appartenente a un giocatore/IP Remove IP ban belonging to a player/IP=Perdona l'IP appartenente a unə giocatore/IP
Failed to unban player/IP.=Errore nel perdonare il giocatore/IP Failed to unban player/IP.=Errore nel perdonare lə giocatore/IP
Unbanned @1.=@1 perdonatǝ Unbanned @1.=@1 perdonatǝ
<name> [<reason>]=<nome> [<ragione>] <name> [<reason>]=<nome> [<ragione>]
Kick a player=Caccia un giocatore Kick a player=Caccia unə giocatore
Failed to kick player @1.=Errore nel cacciare il giocatore @1. Failed to kick player @1.=Errore nel cacciare lə giocatore @1.
Kicked @1.=@1 cacciatǝ. Kicked @1.=@1 cacciatǝ.
[full | quick]=[full | quick] [full | quick]=[full | quick]
Clear all objects in world=Elimina tutti gli oggetti/entità nel mondo Clear all objects in world=Elimina tutti gli oggetti/entità nel mondo
Invalid usage, see /help clearobjects.=Uso incorretto, vedi /help clearobjects. Invalid usage, see /help clearobjects.=Uso incorretto, vedi /help clearobjects.
Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Eliminando tutti gli oggetti/entità. Questo potrebbe richiedere molto tempo e farti eventualmente crashare. (di @1) Clearing all objects. This may take a long time. You may experience a timeout. (by @1)=Eliminando tutti gli oggetti/entità. Questo potrebbe richiedere molto tempo e farti disconnettere. (di @1)
Cleared all objects.=Tutti gli oggetti sono stati eliminati. Cleared all objects.=Tutti gli oggetti sono stati eliminati.
<name> <message>=<nome> <messaggio> <name> <message>=<nome> <messaggio>
Send a direct message to a player=Invia un messaggio privato al giocatore Send a direct message to a player=Invia un messaggio privato a unə giocatore
Invalid usage, see /help msg.=Uso incorretto, vedi /help msg Invalid usage, see /help msg.=Uso incorretto, vedi /help msg
The player @1 is not online.=Il giocatore @1 non è connesso. The player @1 is not online.=Lə giocatore @1 non è connessə.
DM from @1: @2=Messaggio privato da @1: @2 DM from @1: @2=Messaggio privato da @1: @2
Message sent.=Messaggio inviato. Message sent.=Messaggio inviato.
Get the last login time of a player or yourself=Ritorna l'ultimo accesso di un giocatore o di te stessǝ Get the last login time of a player or yourself=Ritorna l'ultimo accesso di unə giocatore o di te stessǝ
@1's last login time was @2.=L'ultimo accesso di @1 è avvenuto il @2 @1's last login time was @2.=L'ultimo accesso di @1 è avvenuto il @2.
@1's last login time is unknown.=L'ultimo accesso di @1 non è conosciuto @1's last login time is unknown.=L'ultimo accesso di @1 è ignoto.
Clear the inventory of yourself or another player=Svuota l'inventario tuo o di un altro giocatore Clear the inventory of yourself or another player=Svuota l'inventario tuo o di un*altrə giocatore
You don't have permission to clear another player's inventory (missing privilege: @1).=Non hai il permesso di svuotare l'inventario di un altro giocatore (privilegio mancante: @1). You don't have permission to clear another player's inventory (missing privilege: @1).=Non hai il permesso di svuotare l'inventario di un*altrə giocatore (privilegio mancante: @1).
@1 cleared your inventory.=@1 ha svuotato il tuo inventario. @1 cleared your inventory.=@1 ha svuotato il tuo inventario.
Cleared @1's inventory.=L'inventario di @1 è stato svuotato. Cleared @1's inventory.=L'inventario di @1 è stato svuotato.
Player must be online to clear inventory!=Il giocatore deve essere connesso per svuotarne l'inventario! Player must be online to clear inventory!=Lə giocatore deve essere connessə per svuotarne l'inventario!
Players can't be killed, damage has been disabled.=I giocatori non possono essere uccisi, il danno è disabilitato. Players can't be killed, damage has been disabled.=Lɜ giocatori non possono essere uccisɜ, il danno è disabilitato.
Player @1 is not online.=Il giocatore @1 non è connesso. Player @1 is not online.= giocatore @1 non è connesso.
You are already dead.=Sei già mortǝ. You are already dead.=Sei già mortǝ.
@1 is already dead.=@1 è già mortǝ. @1 is already dead.=@1 è già mortǝ.
@1 has been killed.=@1 è stato uccisǝ. @1 has been killed.=@1 è stato uccisǝ.
Kill player or yourself=Uccide un giocatore o te stessǝ Kill player or yourself=Uccide unə giocatore o te stessǝ
Invalid parameters (see /help @1).= Invalid parameters (see /help @1).=Parametri non validi (vedi /help @1)
Too many arguments, try using just /help <command>= Too many arguments, try using just /help <command>=Troppi argomenti, prova a usare /help <comando>
Available commands: @1=Comandi disponibili: @1 Available commands: @1=Comandi disponibili: @1
Use '/help <cmd>' to get more information, or '/help all' to list everything.=Usa '/help <comando>' per ottenere più informazioni, o '/help all' per elencare tutti i comandi. Use '/help <cmd>' to get more information, or '/help all' to list everything.=Usa '/help <comando>' per ottenere più informazioni, o '/help all' per elencare tutti i comandi.
Available commands:=Comandi disponibili: Available commands:=Comandi disponibili:
Command not available: @1=Comando non disponibile: @1 Command not available: @1=Comando non disponibile: @1
[all | privs | <cmd>] [-t]= [all | privs | <cmd>] [-t]=[all | privs | <comando>] [-t]
Get help for commands or list privileges (-t: output in chat)= Get help for commands or list privileges (-t: output in chat)=Richiama la finestra d'aiuto dei comandi o dei privilegi (-t: mostra in chat)
Available privileges:=Privilegi disponibili: Available privileges:=Privilegi disponibili:
Command=Comando Command=Comando
Parameters=Parametri Parameters=Parametri
For more information, click on any entry in the list.=Per più informazioni, clicca su una qualsiasi voce dell'elenco. For more information, click on any entry in the list.=Per più informazioni, clicca su una qualsiasi voce dell'elenco.
Double-click to copy the entry to the chat history.=Doppio click per copiare la voce nella cronologia della chat. Double-click to copy the entry to the chat history.=Doppio clic per copiare la voce nella cronologia della chat.
Command: @1 @2=Comando: @1 @2 Command: @1 @2=Comando: @1 @2
Available commands: (see also: /help <cmd>)=Comandi disponibili: (vedi anche /help <comando>) Available commands: (see also: /help <cmd>)=Comandi disponibili: (vedi anche /help <comando>)
Close=Chiudi Close=Chiudi
@ -209,52 +210,38 @@ Privilege=Privilegio
Description=Descrizione Description=Descrizione
print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtro>] | dump [<filtro>] | save [<formato> [<filtro>]] | reset print [<filter>] | dump [<filter>] | save [<format> [<filter>]] | reset=print [<filtro>] | dump [<filtro>] | save [<formato> [<filtro>]] | reset
Handle the profiler and profiling data=Gestisce il profiler e i dati da esso elaborati Handle the profiler and profiling data=Gestisce il profiler e i dati da esso elaborati
Statistics written to action log.=Statistiche scritte nel log delle azioni. Statistics written to action log.=Statistiche scritte nel registro delle azioni.
Statistics were reset.=Le statistiche sono state resettate. Statistics were reset.=Le statistiche sono state resettate.
Usage: @1=Utilizzo: @1 Usage: @1=Utilizzo: @1
Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=I formati supportati sono txt, csv, lua, json e json_pretty (le strutture potrebbero essere soggetti a cambiamenti). Format can be one of txt, csv, lua, json, json_pretty (structures may be subject to change).=I formati supportati sono txt, csv, lua, json e json_pretty (le strutture potrebbero essere soggetti a cambiamenti).
@1 joined the game.= @1 joined the game.=@1 si è connessə.
@1 left the game.= @1 left the game.=@1 si è disconnessə.
@1 left the game (timed out).= @1 left the game (timed out).=@1 si è disconnessə (connessione scaduta).
(no description)=(nessuna descrizione) (no description)=(nessuna descrizione)
Can interact with things and modify the world=Si può interagire con le cose e modificare il mondo Can interact with things and modify the world=Si può interagire con le cose e modificare il mondo
Can speak in chat=Si può parlare in chat Can speak in chat=Si può parlare in chat
Can modify basic privileges (@1)= Can modify basic privileges (@1)=Si possono modificare i privilegi di base (@1)
Can modify privileges=Si possono modificare i privilegi Can modify privileges=Si possono modificare i privilegi
Can teleport self=Si può teletrasportare se stessз Can teleport self=Si può teletrasportare se stessз
Can teleport other players=Si possono teletrasportare gli altri giocatori Can teleport other players=Si possono teletrasportare lɜ altrɜ giocatori
Can set the time of day using /time=Si può impostate l'orario della giornata tramite /time Can set the time of day using /time=Si può impostate l'orario della giornata tramite /time
Can do server maintenance stuff=Si possono eseguire operazioni di manutenzione del server Can do server maintenance stuff=Si possono eseguire operazioni di manutenzione del server
Can bypass node protection in the world=Si può aggirare la protezione dei nodi nel mondo Can bypass node protection in the world=Si può aggirare la protezione dei nodi nel mondo
Can ban and unban players=Si possono bandire e perdonare i giocatori Can ban and unban players=Si possono bandire e perdonare giocatori
Can kick players=Si possono cacciare i giocatori Can kick players=Si possono cacciare giocatori
Can use /give and /giveme=Si possono usare /give e /give me Can use /give and /giveme=Si possono usare /give e /give me
Can use /setpassword and /clearpassword=Si possono usare /setpassword e /clearpassword Can use /setpassword and /clearpassword=Si possono usare /setpassword e /clearpassword
Can use fly mode=Si può usare la modalità volo Can use fly mode=Si può usare la modalità volo
Can use fast mode=Si può usare la modalità rapida Can use fast mode=Si può usare la modalità rapida
Can fly through solid nodes using noclip mode=Si può volare attraverso i nodi solidi con la modalità incorporea Can fly through solid nodes using noclip mode=Si può volare attraverso i nodi solidi con la modalità incorporea
Can use the rollback functionality=Si può usare la funzione di rollback Can use the rollback functionality=Si può usare la funzione di rollback
Can enable wireframe= Can enable wireframe=Si può abilitare la vista reticolata
Unknown Item=Oggetto sconosciuto Unknown Item=Oggetto sconosciuto
Air=Aria Air=Aria
Ignore=Ignora Ignore=Ignora
You can't place 'ignore' nodes!=Non puoi piazzare nodi 'ignore'! You can't place 'ignore' nodes!=Non puoi piazzare nodi 'ignore'!
Values below show absolute/relative times spend per server step by the instrumented function.= Values below show absolute/relative times spend per server step by the instrumented function.=I valori sottostanti mostrano i tempi assoluti/relativi impiegati su ogni singolo step dalla funzione analizzata
A total of @1 sample(s) were taken.= A total of @1 sample(s) were taken.=Son stati ottenuti campioni per un totale di @1.
The output is limited to '@1'.= The output is limited to '@1'.=L'output è limitato a '@1'.
Saving of profile failed: @1= Saving of profile failed: @1=Errore nel salvare il profilo: @1
Profile saved to @1= Profile saved to @1=Profilo salvato in @1
##### not used anymore #####
Set player's password=Imposta la password del giocatore
Invalid time.=Orario non valido.
[all | privs | <cmd>]=[all | privs | <comando>]
Get help for commands or list privileges=Richiama la finestra d'aiuto dei comandi o dei privilegi
Allows enabling various debug options that may affect gameplay=Permette di abilitare varie opzioni di debug che potrebbero influenzare l'esperienza di gioco
[<delay_in_seconds> | -1] [reconnect] [<message>]=[<ritardo_in_secondi> | -1] [reconnect] [<messaggio>]
Shutdown server (-1 cancels a delayed shutdown)=Arresta il server (-1 annulla un arresto programmato)
<name> (<privilege> | all)=<nome> (<privilegio> | all)
<privilege> | all=<privilegio> | all
Can modify 'shout' and 'interact' privileges=Si possono modificare i privilegi 'shout' e 'interact'

@ -695,10 +695,11 @@ local function resolve_auto_install_spec()
return nil return nil
end end
local spec = store.aliases[auto_install_spec] or auto_install_spec
local resolved = nil local resolved = nil
for _, pkg in ipairs(store.packages_full_unordered) do for _, pkg in ipairs(store.packages_full_unordered) do
if pkg.id == auto_install_spec then if pkg.id == spec then
resolved = pkg resolved = pkg
break break
end end

@ -27,9 +27,9 @@ local core_developers = {
"Krock/SmallJoker <mk939@ymail.com>", "Krock/SmallJoker <mk939@ymail.com>",
"Lars Hofhansl <larsh@apache.org>", "Lars Hofhansl <larsh@apache.org>",
"v-rob <robinsonvincent89@gmail.com>", "v-rob <robinsonvincent89@gmail.com>",
"Hugues Ross <hugues.ross@gmail.com>", "Desour/DS",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>", "srifqi",
"Desour", "Gregor Parzefall (grorp)",
} }
-- currently only https://github.com/orgs/minetest/teams/triagers/members -- currently only https://github.com/orgs/minetest/teams/triagers/members
@ -43,18 +43,19 @@ local core_team = {
-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py -- For updating active/previous contributors, see the script in ./util/gather_git_credits.py
local active_contributors = { local active_contributors = {
"Wuzzy [Features, translations, devtest]", "Wuzzy [Features, translations, documentation]",
"Lars Müller [Bugfixes and entity features]", "numzero [Optimizations, work on OpenGL driver]",
"paradust7 [Bugfixes]", "ROllerozxa [Bugfixes, Mainmenu]",
"ROllerozxa [Bugfixes, Android]", "Lars Müller [Bugfixes]",
"srifqi [Android, translations]", "AFCMS [Documentation]",
"Lexi Hale [Particlespawner animation]",
"savilli [Bugfixes]", "savilli [Bugfixes]",
"fluxionary [Bugfixes]", "fluxionary [Bugfixes]",
"Gregor Parzefall [Bugfixes]", "Bradley Pierce (Thresher) [Documentation]",
"Stvk imension [Android]",
"JosiahWI [Code cleanups]",
"OgelGames [UI, Bugfixes]",
"ndren [Bugfixes]",
"Abdou-31 [Documentation]", "Abdou-31 [Documentation]",
"pecksin [Bouncy physics]",
"Daroc Alden [Fixes]",
} }
local previous_core_developers = { local previous_core_developers = {
@ -75,13 +76,14 @@ local previous_core_developers = {
"Pierre-Yves Rollo <dev@pyrollo.com>", "Pierre-Yves Rollo <dev@pyrollo.com>",
"hecks", "hecks",
"Jude Melton-Houghton (TurkeyMcMac) [RIP]", "Jude Melton-Houghton (TurkeyMcMac) [RIP]",
"Hugues Ross <hugues.ross@gmail.com>",
"Dmitry Kostenko (x2048) <codeforsmile@gmail.com>",
} }
local previous_contributors = { local previous_contributors = {
"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]", "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net> [Minetest logo]",
"red-001 <red-001@outlook.ie>", "red-001 <red-001@outlook.ie>",
"Giuseppe Bilotta", "Giuseppe Bilotta",
"numzero",
"HybridDog", "HybridDog",
"ClobberXD", "ClobberXD",
"Dániel Juhász (juhdanad) <juhdanad@gmail.com>", "Dániel Juhász (juhdanad) <juhdanad@gmail.com>",
@ -126,12 +128,6 @@ return {
} }
table.insert_all(hypertext, { table.insert_all(hypertext, {
"<style color=#000>Dedication of the current release</style>\n",
"The 5.7.0 release is dedicated to the memory of\n",
"Minetest developer Jude Melton-Houghton (TurkeyMcMac)\n",
"who died on February 1, 2023.\n",
"Our thoughts are with his family and friends.\n",
"\n",
"<heading>", fgettext_ne("Core Developers"), "</heading>\n", "<heading>", fgettext_ne("Core Developers"), "</heading>\n",
}) })
prepare_credits(hypertext, core_developers) prepare_credits(hypertext, core_developers)

@ -283,11 +283,16 @@ void GUIEngine::run()
else else
drawBackground(driver); drawBackground(driver);
drawHeader(driver);
drawFooter(driver); drawFooter(driver);
m_rendering_engine->get_gui_env()->drawAll(); m_rendering_engine->get_gui_env()->drawAll();
// The header *must* be drawn after the menu because it uses
// GUIFormspecMenu::getAbsoluteRect().
// The header *can* be drawn after the menu because it never intersects
// the menu.
drawHeader(driver);
driver->endScene(); driver->endScene();
IrrlichtDevice *device = m_rendering_engine->get_raw_device(); IrrlichtDevice *device = m_rendering_engine->get_raw_device();
@ -478,30 +483,57 @@ void GUIEngine::drawHeader(video::IVideoDriver *driver)
video::ITexture* texture = m_textures[TEX_LAYER_HEADER].texture; video::ITexture* texture = m_textures[TEX_LAYER_HEADER].texture;
/* If no texture, draw nothing */ // If no texture, draw nothing
if (!texture) if (!texture)
return; return;
/*
* Calculate the maximum rectangle
*/
core::rect<s32> formspec_rect = m_menu->getAbsoluteRect();
// 4 px of padding on each side
core::rect<s32> max_rect(4, 4, screensize.Width - 8, formspec_rect.UpperLeftCorner.Y - 8);
// If no space (less than 16x16 px), draw nothing
if (max_rect.getWidth() < 16 || max_rect.getHeight() < 16)
return;
/*
* Calculate the preferred rectangle
*/
f32 mult = (((f32)screensize.Width / 2.0)) / f32 mult = (((f32)screensize.Width / 2.0)) /
((f32)texture->getOriginalSize().Width); ((f32)texture->getOriginalSize().Width);
v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult, v2s32 splashsize(((f32)texture->getOriginalSize().Width) * mult,
((f32)texture->getOriginalSize().Height) * mult); ((f32)texture->getOriginalSize().Height) * mult);
// Don't draw the header if there isn't enough room
s32 free_space = (((s32)screensize.Height)-320)/2; s32 free_space = (((s32)screensize.Height)-320)/2;
if (free_space > splashsize.Y) { core::rect<s32> desired_rect(0, 0, splashsize.X, splashsize.Y);
core::rect<s32> splashrect(0, 0, splashsize.X, splashsize.Y); desired_rect += v2s32((screensize.Width/2)-(splashsize.X/2),
splashrect += v2s32((screensize.Width/2)-(splashsize.X/2),
((free_space/2)-splashsize.Y/2)+10); ((free_space/2)-splashsize.Y/2)+10);
draw2DImageFilterScaled(driver, texture, splashrect, /*
* Make the preferred rectangle fit into the maximum rectangle
*/
// 1. Scale
f32 scale = std::min((f32)max_rect.getWidth() / (f32)desired_rect.getWidth(),
(f32)max_rect.getHeight() / (f32)desired_rect.getHeight());
if (scale < 1.0f) {
v2s32 old_center = desired_rect.getCenter();
desired_rect.LowerRightCorner.X = desired_rect.UpperLeftCorner.X + desired_rect.getWidth() * scale;
desired_rect.LowerRightCorner.Y = desired_rect.UpperLeftCorner.Y + desired_rect.getHeight() * scale;
desired_rect += old_center - desired_rect.getCenter();
}
// 2. Move
desired_rect.constrainTo(max_rect);
draw2DImageFilterScaled(driver, texture, desired_rect,
core::rect<s32>(core::position2d<s32>(0,0), core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())), core::dimension2di(texture->getOriginalSize())),
NULL, NULL, true); NULL, NULL, true);
} }
}
/******************************************************************************/ /******************************************************************************/
void GUIEngine::drawFooter(video::IVideoDriver *driver) void GUIEngine::drawFooter(video::IVideoDriver *driver)

@ -247,6 +247,14 @@ std::vector<std::string>* GUIFormSpecMenu::getDropDownValues(const std::string &
return NULL; return NULL;
} }
// This will only return a meaningful value if called after drawMenu().
core::rect<s32> GUIFormSpecMenu::getAbsoluteRect()
{
core::rect<s32> rect = AbsoluteRect;
rect.UpperLeftCorner.Y += m_tabheader_upper_edge;
return rect;
}
v2s32 GUIFormSpecMenu::getElementBasePos(const std::vector<std::string> *v_pos) v2s32 GUIFormSpecMenu::getElementBasePos(const std::vector<std::string> *v_pos)
{ {
v2f32 pos_f = v2f32(padding.X, padding.Y) + pos_offset * spacing; v2f32 pos_f = v2f32(padding.X, padding.Y) + pos_offset * spacing;
@ -2104,6 +2112,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data, const std::string &elemen
e->setActiveTab(tab_index); e->setActiveTab(tab_index);
m_fields.push_back(spec); m_fields.push_back(spec);
m_tabheader_upper_edge = MYMIN(m_tabheader_upper_edge, rect.UpperLeftCorner.Y);
} }
void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element) void GUIFormSpecMenu::parseItemImageButton(parserData* data, const std::string &element)
@ -3105,6 +3114,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
m_formspec_version = 1; m_formspec_version = 1;
m_bgcolor = video::SColor(140, 0, 0, 0); m_bgcolor = video::SColor(140, 0, 0, 0);
m_tabheader_upper_edge = 0;
{ {
v3f formspec_bgcolor = g_settings->getV3F("formspec_fullscreen_bg_color"); v3f formspec_bgcolor = g_settings->getV3F("formspec_fullscreen_bg_color");
@ -3633,7 +3643,7 @@ void GUIFormSpecMenu::drawMenu()
NULL, m_client, IT_ROT_HOVERED); NULL, m_client, IT_ROT_HOVERED);
} }
/* TODO find way to show tooltips on touchscreen */ // On touchscreens, m_pointer is set by GUIModalMenu::preprocessEvent instead.
#ifndef HAVE_TOUCHSCREENGUI #ifndef HAVE_TOUCHSCREENGUI
m_pointer = RenderingEngine::get_raw_device()->getCursorControl()->getPosition(); m_pointer = RenderingEngine::get_raw_device()->getCursorControl()->getPosition();
#endif #endif
@ -4191,13 +4201,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
/* Mouse event other than movement, or crossing the border of inventory /* Mouse event other than movement, or crossing the border of inventory
field while holding left, right, or middle mouse button field while holding left, right, or middle mouse button
or touch event (for touch screen devices)
*/ */
if (event.EventType == EET_MOUSE_INPUT_EVENT && if ((event.EventType == EET_MOUSE_INPUT_EVENT &&
(event.MouseInput.Event != EMIE_MOUSE_MOVED || (event.MouseInput.Event != EMIE_MOUSE_MOVED ||
((event.MouseInput.isLeftPressed() || ((event.MouseInput.isLeftPressed() ||
event.MouseInput.isRightPressed() || event.MouseInput.isRightPressed() ||
event.MouseInput.isMiddlePressed()) && event.MouseInput.isMiddlePressed()) &&
getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) { getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) ||
event.EventType == EET_TOUCH_INPUT_EVENT) {
// Get selected item and hovered/clicked item (s) // Get selected item and hovered/clicked item (s)
@ -4266,6 +4278,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
ButtonEventType button = BET_OTHER; ButtonEventType button = BET_OTHER;
ButtonEventType updown = BET_OTHER; ButtonEventType updown = BET_OTHER;
bool mouse_shift = false;
if (event.EventType == EET_MOUSE_INPUT_EVENT) {
mouse_shift = event.MouseInput.Shift;
switch (event.MouseInput.Event) { switch (event.MouseInput.Event) {
case EMIE_LMOUSE_PRESSED_DOWN: case EMIE_LMOUSE_PRESSED_DOWN:
button = BET_LEFT; updown = BET_DOWN; button = BET_LEFT; updown = BET_DOWN;
@ -4296,6 +4311,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
default: default:
break; break;
} }
}
#ifdef HAVE_TOUCHSCREENGUI
// The second touch (see GUIModalMenu::preprocessEvent() function)
ButtonEventType touch = BET_OTHER;
if (event.EventType == EET_TOUCH_INPUT_EVENT) {
if (event.TouchInput.Event == ETIE_LEFT_UP)
touch = BET_RIGHT;
}
#endif
// Set this number to a positive value to generate a move action // Set this number to a positive value to generate a move action
// from m_selected_item to s. // from m_selected_item to s.
@ -4322,6 +4347,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if (m_held_mouse_button != BET_OTHER) if (m_held_mouse_button != BET_OTHER)
break; break;
if (button == BET_LEFT || button == BET_RIGHT || button == BET_MIDDLE) if (button == BET_LEFT || button == BET_RIGHT || button == BET_MIDDLE)
m_held_mouse_button = button; m_held_mouse_button = button;
@ -4341,13 +4367,13 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
// Craft preview has been clicked: craft // Craft preview has been clicked: craft
if (button == BET_MIDDLE) if (button == BET_MIDDLE)
craft_amount = 10; craft_amount = 10;
else if (event.MouseInput.Shift && button == BET_LEFT) else if (mouse_shift && button == BET_LEFT)
craft_amount = list_s->getItem(s.i).getStackMax(m_client->idef()); craft_amount = list_s->getItem(s.i).getStackMax(m_client->idef());
else else
craft_amount = 1; craft_amount = 1;
// Holding shift moves the crafted item to the inventory // Holding shift moves the crafted item to the inventory
m_shift_move_after_craft = event.MouseInput.Shift; m_shift_move_after_craft = mouse_shift;
} else if (!m_selected_item && button != BET_WHEEL_UP && !empty) { } else if (!m_selected_item && button != BET_WHEEL_UP && !empty) {
// Non-empty stack has been clicked: select or shift-move it // Non-empty stack has been clicked: select or shift-move it
@ -4361,7 +4387,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
else if (button == BET_LEFT) else if (button == BET_LEFT)
count = s_count; count = s_count;
if (event.MouseInput.Shift) { if (mouse_shift) {
// Shift pressed: move item, right click moves 1 // Shift pressed: move item, right click moves 1
shift_move_amount = button == BET_RIGHT ? 1 : count; shift_move_amount = button == BET_RIGHT ? 1 : count;
} else { } else {
@ -4382,7 +4408,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
else if (button == BET_LEFT) else if (button == BET_LEFT)
move_amount = m_selected_amount; move_amount = m_selected_amount;
if (event.MouseInput.Shift && !identical && matching) { if (mouse_shift && !identical && matching) {
// Shift-move all items the same as the selected item to the next list // Shift-move all items the same as the selected item to the next list
move_amount = 0; move_amount = 0;
@ -4520,7 +4546,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if (!s.isValid() || s.listname == "craftpreview") if (!s.isValid() || s.listname == "craftpreview")
break; break;
if (!m_selected_item && event.MouseInput.Shift) { if (!m_selected_item && mouse_shift) {
// Shift-move items while dragging // Shift-move items while dragging
if (m_held_mouse_button == BET_RIGHT) if (m_held_mouse_button == BET_RIGHT)
shift_move_amount = 1; shift_move_amount = 1;
@ -4570,7 +4596,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
case BET_OTHER: { case BET_OTHER: {
// Some other mouse event has occured // Some other mouse event has occured
// Currently only left-double-click should trigger this // Currently only left-double-click should trigger this
if (!s.isValid() || event.MouseInput.Event != EMIE_LMOUSE_DOUBLE_CLICK) if (!s.isValid() || event.EventType != EET_MOUSE_INPUT_EVENT ||
event.MouseInput.Event != EMIE_LMOUSE_DOUBLE_CLICK)
break; break;
// Only do the pickup all thing when putting down an item. // Only do the pickup all thing when putting down an item.
@ -4638,6 +4665,28 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
break; break;
} }
#ifdef HAVE_TOUCHSCREENGUI
if (touch == BET_RIGHT && m_selected_item && !m_left_dragging) {
if (!s.isValid()) {
// Not a valid slot
if (!getAbsoluteClippingRect().isPointInside(m_pointer))
// Is outside the menu
drop_amount = 1;
} else {
// Over a valid slot
move_amount = 1;
if (identical) {
// Change the selected amount instead of moving
if (move_amount >= m_selected_amount)
m_selected_amount = 0;
else
m_selected_amount -= move_amount;
move_amount = 0;
}
}
}
#endif
// Update left-dragged slots // Update left-dragged slots
if (m_left_dragging && m_left_drag_stacks.size() > 1) { if (m_left_dragging && m_left_drag_stacks.size() > 1) {
// The split amount will always at least one, because the number // The split amount will always at least one, because the number
@ -5004,6 +5053,11 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
} }
} }
#ifdef HAVE_TOUCHSCREENGUI
if (m_second_touch)
return true; // Stop propagating the event
#endif
return Parent ? Parent->OnEvent(event) : false; return Parent ? Parent->OnEvent(event) : false;
} }

@ -282,6 +282,9 @@ public:
GUITable* getTable(const std::string &tablename); GUITable* getTable(const std::string &tablename);
std::vector<std::string>* getDropDownValues(const std::string &name); std::vector<std::string>* getDropDownValues(const std::string &name);
// This will only return a meaningful value if called after drawMenu().
core::rect<s32> getAbsoluteRect();
#ifdef __ANDROID__ #ifdef __ANDROID__
bool getAndroidUIInput(); bool getAndroidUIInput();
#endif #endif
@ -499,6 +502,9 @@ private:
int m_btn_height; int m_btn_height;
gui::IGUIFont *m_font = nullptr; gui::IGUIFont *m_font = nullptr;
// used by getAbsoluteRect
s32 m_tabheader_upper_edge = 0;
}; };
class FormspecFormSource: public IFormSource class FormspecFormSource: public IFormSource

@ -99,6 +99,7 @@ void GUIInventoryList::draw()
(i / m_geom.X) * m_slot_spacing.Y); (i / m_geom.X) * m_slot_spacing.Y);
core::rect<s32> rect = imgrect + base_pos + p; core::rect<s32> rect = imgrect + base_pos + p;
ItemStack item = ilist->getItem(item_i); ItemStack item = ilist->getItem(item_i);
ItemStack orig_item = item;
bool selected = selected_item bool selected = selected_item
&& m_invmgr->getInventory(selected_item->inventoryloc) == inv && m_invmgr->getInventory(selected_item->inventoryloc) == inv
@ -147,13 +148,19 @@ void GUIInventoryList::draw()
// Draw item stack // Draw item stack
drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect, drawItemStack(driver, m_font, item, rect, &AbsoluteClippingRect,
client, rotation_kind); client, rotation_kind);
// Add hovering tooltip
if (hovering && !selected_item) {
std::string tooltip = item.getDescription(client->idef());
if (m_fs_menu->doTooltipAppendItemname())
tooltip += "\n[" + item.name + "]";
m_fs_menu->addHoveredItemTooltip(tooltip);
} }
// Add hovering tooltip
bool show_tooltip = !item.empty() && hovering && !selected_item;
#ifdef HAVE_TOUCHSCREENGUI
// Make it possible to see item tooltips on touchscreens
show_tooltip |= hovering && selected && m_fs_menu->getSelectedAmount() != 0;
#endif
if (show_tooltip) {
std::string tooltip = orig_item.getDescription(client->idef());
if (m_fs_menu->doTooltipAppendItemname())
tooltip += "\n[" + orig_item.name + "]";
m_fs_menu->addHoveredItemTooltip(tooltip);
} }
} }

@ -278,12 +278,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
irr_ptr<GUIModalMenu> holder; irr_ptr<GUIModalMenu> holder;
holder.grab(this); // keep this alive until return (it might be dropped downstream [?]) holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
switch ((int)event.TouchInput.touchedCount) { if (event.TouchInput.ID == 0) {
case 1: {
if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED) if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED)
m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y); m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y);
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
m_down_pos = m_pointer;
gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer)); gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer));
if (event.TouchInput.Event == ETIE_PRESSED_DOWN) if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
Environment->setFocus(hovered); Environment->setFocus(hovered);
@ -298,26 +295,19 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
if (event.TouchInput.Event == ETIE_LEFT_UP) if (event.TouchInput.Event == ETIE_LEFT_UP)
leave(); leave();
return ret; return ret;
} } else if (event.TouchInput.ID == 1) {
case 2: { if (event.TouchInput.Event != ETIE_LEFT_UP)
if (event.TouchInput.Event != ETIE_PRESSED_DOWN)
return true; // ignore return true; // ignore
auto focused = Environment->getFocus(); auto focused = Environment->getFocus();
if (!focused) if (!focused)
return true; return true;
SEvent rclick_event{}; // The second-touch event is propagated as is (not converted).
rclick_event.EventType = EET_MOUSE_INPUT_EVENT; m_second_touch = true;
rclick_event.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN; focused->OnEvent(event);
rclick_event.MouseInput.ButtonStates = EMBSM_LEFT | EMBSM_RIGHT; m_second_touch = false;
rclick_event.MouseInput.X = m_pointer.X;
rclick_event.MouseInput.Y = m_pointer.Y;
focused->OnEvent(rclick_event);
rclick_event.MouseInput.Event = EMIE_RMOUSE_LEFT_UP;
rclick_event.MouseInput.ButtonStates = EMBSM_LEFT;
focused->OnEvent(rclick_event);
return true; return true;
} } else {
default: // ignored // Any other touch after the second touch is ignored.
return true; return true;
} }
} }

@ -77,7 +77,8 @@ protected:
std::string m_jni_field_name; std::string m_jni_field_name;
#endif #endif
#ifdef HAVE_TOUCHSCREENGUI #ifdef HAVE_TOUCHSCREENGUI
v2s32 m_down_pos; // This is set to true if the menu is currently processing a second-touch event.
bool m_second_touch = false;
bool m_touchscreen_visible = true; bool m_touchscreen_visible = true;
#endif #endif

@ -6,7 +6,7 @@ from collections import defaultdict
codefiles = r"(\.[ch](pp)?|\.lua|\.md|\.cmake|\.java|\.gradle|Makefile|CMakeLists\.txt)$" codefiles = r"(\.[ch](pp)?|\.lua|\.md|\.cmake|\.java|\.gradle|Makefile|CMakeLists\.txt)$"
# two minor versions back, for "Active Contributors" # two minor versions back, for "Active Contributors"
REVS_ACTIVE = "5.2.0..HEAD" REVS_ACTIVE = "5.6.0..HEAD"
# all time, for "Previous Contributors" # all time, for "Previous Contributors"
REVS_PREVIOUS = "HEAD" REVS_PREVIOUS = "HEAD"