Remove SFINV chapter
This commit is contained in:
parent
f8c9da8261
commit
df46f465cd
@ -35,16 +35,16 @@ unexpected windows tend to disrupt gameplay.
|
|||||||
|
|
||||||
- [Real or Legacy Coordinates](#real-or-legacy-coordinates)
|
- [Real or Legacy Coordinates](#real-or-legacy-coordinates)
|
||||||
- [Anatomy of a Formspec](#anatomy-of-a-formspec)
|
- [Anatomy of a Formspec](#anatomy-of-a-formspec)
|
||||||
- [Elements](#elements)
|
- [Elements](#elements)
|
||||||
- [Header](#header)
|
- [Header](#header)
|
||||||
- [Guessing Game](#guessing-game)
|
- [Guessing Game](#guessing-game)
|
||||||
- [Padding and Spacing](#padding-and-spacing)
|
- [Padding and Spacing](#padding-and-spacing)
|
||||||
- [Receiving Formspec Submissions](#receiving-formspec-submissions)
|
- [Receiving Formspec Submissions](#receiving-formspec-submissions)
|
||||||
- [Contexts](#contexts)
|
- [Contexts](#contexts)
|
||||||
- [Formspec Sources](#formspec-sources)
|
- [Formspec Sources](#formspec-sources)
|
||||||
- [Node Meta Formspecs](#node-meta-formspecs)
|
- [Node Meta Formspecs](#node-meta-formspecs)
|
||||||
- [Player Inventory Formspecs](#player-inventory-formspecs)
|
- [Player Inventory Formspecs](#player-inventory-formspecs)
|
||||||
- [Your Turn](#your-turn)
|
- [Your Turn](#your-turn)
|
||||||
|
|
||||||
|
|
||||||
## Real or Legacy Coordinates
|
## Real or Legacy Coordinates
|
||||||
@ -365,9 +365,9 @@ The player inventory formspec is the one shown when the player presses i.
|
|||||||
The global callback is used to receive events from this formspec, and the
|
The global callback is used to receive events from this formspec, and the
|
||||||
formname is `""`.
|
formname is `""`.
|
||||||
|
|
||||||
There are a number of different mods which allow multiple mods to customise
|
There are a number of different mods which allow multiple mods to customise the
|
||||||
the player inventory. The officially recommended mod is
|
player inventory. Minetest Game uses
|
||||||
[Simple Fast Inventory (sfinv)](sfinv.html), and is included in Minetest Game.
|
[SFINV](https://github.com/rubenwardy/sfinv/blob/master/Tutorial.md).
|
||||||
|
|
||||||
|
|
||||||
### Your Turn
|
### Your Turn
|
||||||
|
@ -1,242 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "SFINV: Inventory Formspec"
|
sitemap: false
|
||||||
layout: default
|
|
||||||
root: ../..
|
|
||||||
idx: 4.7
|
|
||||||
redirect_from: /en/chapters/sfinv.html
|
redirect_from: /en/chapters/sfinv.html
|
||||||
|
redirect_to: "https://github.com/rubenwardy/sfinv/blob/master/Tutorial.md"
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduction <!-- omit in toc -->
|
|
||||||
|
|
||||||
Simple Fast Inventory (SFINV) is a mod found in Minetest Game that is used to
|
|
||||||
create the player's inventory [formspec](formspecs.html). SFINV comes with
|
|
||||||
an API that allows you to add and otherwise manage the pages shown.
|
|
||||||
|
|
||||||
Whilst SFINV by default shows pages as tabs, pages are called pages
|
|
||||||
because it is entirely possible that a mod or game decides to show them in
|
|
||||||
some other format instead.
|
|
||||||
For example, multiple pages could be shown in one formspec.
|
|
||||||
|
|
||||||
- [Registering a Page](#registering-a-page)
|
|
||||||
- [Receiving events](#receiving-events)
|
|
||||||
- [Conditionally showing to players](#conditionally-showing-to-players)
|
|
||||||
- [on_enter and on_leave callbacks](#onenter-and-onleave-callbacks)
|
|
||||||
- [Adding to an existing page](#adding-to-an-existing-page)
|
|
||||||
|
|
||||||
## Registering a Page
|
|
||||||
|
|
||||||
SFINV provides the aptly named `sfinv.register_page` function to create pages.
|
|
||||||
Simply call the function with the page's name and its definition:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
sfinv.register_page("mymod:hello", {
|
|
||||||
title = "Hello!",
|
|
||||||
get = function(self, player, context)
|
|
||||||
return sfinv.make_formspec(player, context,
|
|
||||||
"label[0.1,0.1;Hello world!]", true)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
The `make_formspec` function surrounds your formspec with SFINV's formspec code.
|
|
||||||
The fourth parameter, currently set as `true`, determines whether the
|
|
||||||
player's inventory is shown.
|
|
||||||
|
|
||||||
Let's make things more exciting; here is the code for the formspec generation
|
|
||||||
part of a player admin tab. This tab will allow admins to kick or ban players by
|
|
||||||
selecting them in a list and clicking a button.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
sfinv.register_page("myadmin:myadmin", {
|
|
||||||
title = "Tab",
|
|
||||||
get = function(self, player, context)
|
|
||||||
local players = {}
|
|
||||||
context.myadmin_players = players
|
|
||||||
|
|
||||||
-- Using an array to build a formspec is considerably faster
|
|
||||||
local formspec = {
|
|
||||||
"textlist[0.1,0.1;7.8,3;playerlist;"
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Add all players to the text list, and to the players list
|
|
||||||
local is_first = true
|
|
||||||
for _ , player in pairs(minetest.get_connected_players()) do
|
|
||||||
local player_name = player:get_player_name()
|
|
||||||
players[#players + 1] = player_name
|
|
||||||
if not is_first then
|
|
||||||
formspec[#formspec + 1] = ","
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] =
|
|
||||||
minetest.formspec_escape(player_name)
|
|
||||||
is_first = false
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] = "]"
|
|
||||||
|
|
||||||
-- Add buttons
|
|
||||||
formspec[#formspec + 1] = "button[0.1,3.3;2,1;kick;Kick]"
|
|
||||||
formspec[#formspec + 1] = "button[2.1,3.3;2,1;ban;Kick + Ban]"
|
|
||||||
|
|
||||||
-- Wrap the formspec in sfinv's layout
|
|
||||||
-- (ie: adds the tabs and background)
|
|
||||||
return sfinv.make_formspec(player, context,
|
|
||||||
table.concat(formspec, ""), false)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
There's nothing new about the above code; all the concepts are
|
|
||||||
covered above and in previous chapters.
|
|
||||||
|
|
||||||
<figure>
|
|
||||||
<img src="{{ page.root }}//static/sfinv_admin_fs.png" alt="Player Admin Page">
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
## Receiving events
|
|
||||||
|
|
||||||
You can receive formspec events by adding a `on_player_receive_fields` function
|
|
||||||
to a sfinv definition.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_player_receive_fields = function(self, player, context, fields)
|
|
||||||
-- TODO: implement this
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
`on_player_receive_fields` works the same as
|
|
||||||
`minetest.register_on_player_receive_fields`, except that `context` is
|
|
||||||
given instead of `formname`.
|
|
||||||
Please note that SFINV will consume events relevant to itself, such as
|
|
||||||
navigation tab events, so you won't receive them in this callback.
|
|
||||||
|
|
||||||
Now let's implement the `on_player_receive_fields` for our admin mod:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_player_receive_fields = function(self, player, context, fields)
|
|
||||||
-- text list event, check event type and set index if selection changed
|
|
||||||
if fields.playerlist then
|
|
||||||
local event = minetest.explode_textlist_event(fields.playerlist)
|
|
||||||
if event.type == "CHG" then
|
|
||||||
context.myadmin_selected_idx = event.index
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Kick button was pressed
|
|
||||||
elseif fields.kick then
|
|
||||||
local player_name =
|
|
||||||
context.myadmin_players[context.myadmin_selected_idx]
|
|
||||||
if player_name then
|
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
|
||||||
"Kicked " .. player_name)
|
|
||||||
minetest.kick_player(player_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Ban button was pressed
|
|
||||||
elseif fields.ban then
|
|
||||||
local player_name =
|
|
||||||
context.myadmin_players[context.myadmin_selected_idx]
|
|
||||||
if player_name then
|
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
|
||||||
"Banned " .. player_name)
|
|
||||||
minetest.ban_player(player_name)
|
|
||||||
minetest.kick_player(player_name, "Banned")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
There's a rather large problem with this, however. Anyone can kick or ban players! You
|
|
||||||
need a way to only show this to players with the kick or ban privileges.
|
|
||||||
Luckily SFINV allows you to do this!
|
|
||||||
|
|
||||||
## Conditionally showing to players
|
|
||||||
|
|
||||||
You can add an `is_in_nav` function to your page's definition if you'd like to
|
|
||||||
control when the page is shown:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
is_in_nav = function(self, player, context)
|
|
||||||
local privs = minetest.get_player_privs(player:get_player_name())
|
|
||||||
return privs.kick or privs.ban
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
If you only need to check one priv or want to perform an 'and', you should use
|
|
||||||
`minetest.check_player_privs()` instead of `get_player_privs`.
|
|
||||||
|
|
||||||
Note that the `is_in_nav` is only called when the player's inventory formspec is
|
|
||||||
generated. This happens when a player joins the game, switches tabs, or a mod
|
|
||||||
requests for SFINV to regenerate.
|
|
||||||
|
|
||||||
This means that you need to manually request that SFINV regenerates the inventory
|
|
||||||
formspec on any events that may change `is_in_nav`'s result. In our case,
|
|
||||||
we need to do that whenever kick or ban is granted or revoked to a player:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local function on_grant_revoke(grantee, granter, priv)
|
|
||||||
if priv ~= "kick" and priv ~= "ban" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local player = minetest.get_player_by_name(grantee)
|
|
||||||
if not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local context = sfinv.get_or_create_context(player)
|
|
||||||
if context.page ~= "myadmin:myadmin" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
sfinv.set_player_inventory_formspec(player, context)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_priv_grant(on_grant_revoke)
|
|
||||||
minetest.register_on_priv_revoke(on_grant_revoke)
|
|
||||||
```
|
|
||||||
|
|
||||||
## on_enter and on_leave callbacks
|
|
||||||
|
|
||||||
A player *enters* a tab when the tab is selected and *leaves* a
|
|
||||||
tab when another tab is about to be selected.
|
|
||||||
It's possible for multiple pages to be selected if a custom theme is
|
|
||||||
used.
|
|
||||||
|
|
||||||
Note that these events may not be triggered by the player.
|
|
||||||
The player may not even have the formspec open at that time.
|
|
||||||
For example, on_enter is called for the home page when a player
|
|
||||||
joins the game even before they open their inventory.
|
|
||||||
|
|
||||||
It's not possible to cancel a page change, as that would potentially
|
|
||||||
confuse the player.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_enter = function(self, player, context)
|
|
||||||
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_leave = function(self, player, context)
|
|
||||||
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
## Adding to an existing page
|
|
||||||
|
|
||||||
To add content to an existing page, you will need to override the page
|
|
||||||
and modify the returned formspec.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local old_func = sfinv.registered_pages["sfinv:crafting"].get
|
|
||||||
sfinv.override_page("sfinv:crafting", {
|
|
||||||
get = function(self, player, context, ...)
|
|
||||||
local ret = old_func(self, player, context, ...)
|
|
||||||
|
|
||||||
if type(ret) == "table" then
|
|
||||||
ret.formspec = ret.formspec .. "label[0,0;Hello]"
|
|
||||||
else
|
|
||||||
-- Backwards compatibility
|
|
||||||
ret = ret .. "label[0,0;Hello]"
|
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
@ -29,16 +29,16 @@ Tieni presente che se non si ha bisogno di ricevere input dal giocatore, per ese
|
|||||||
|
|
||||||
- [Coordinate reali o datate](#coordinate-reali-o-datate)
|
- [Coordinate reali o datate](#coordinate-reali-o-datate)
|
||||||
- [Anatomia di un formspec](#anatomia-di-un-formspec)
|
- [Anatomia di un formspec](#anatomia-di-un-formspec)
|
||||||
- [Elementi](#elementi)
|
- [Elementi](#elementi)
|
||||||
- [Intestazione](#intestazione)
|
- [Intestazione](#intestazione)
|
||||||
- [Esempio: indovina un numero](#esempio-indovina-un-numero)
|
- [Esempio: indovina un numero](#esempio-indovina-un-numero)
|
||||||
- [Imbottitura e spaziatura](#imbottitura-e-spaziatura)
|
- [Imbottitura e spaziatura](#imbottitura-e-spaziatura)
|
||||||
- [Ricevere i moduli di compilazione](#ricevere-i-moduli-di-compilazione)
|
- [Ricevere i moduli di compilazione](#ricevere-i-moduli-di-compilazione)
|
||||||
- [Contesti](#contesti)
|
- [Contesti](#contesti)
|
||||||
- [Ricavare un formspec](#ricavare-un-formspec)
|
- [Ricavare un formspec](#ricavare-un-formspec)
|
||||||
- [Formspec nei nodi](#formspec-nei-nodi)
|
- [Formspec nei nodi](#formspec-nei-nodi)
|
||||||
- [Inventario del giocatore](#inventario-del-giocatore)
|
- [Inventario del giocatore](#inventario-del-giocatore)
|
||||||
- [Il tuo turno](#il-tuo-turno)
|
- [Il tuo turno](#il-tuo-turno)
|
||||||
|
|
||||||
|
|
||||||
## Coordinate reali o datate
|
## Coordinate reali o datate
|
||||||
@ -321,7 +321,7 @@ L'inventario del giocatore è un formspec, che viene mostrato al premere "I".
|
|||||||
Il callback globale viene usato per ricevere eventi dall'inventario, e il suo nome è `""`.
|
Il callback globale viene usato per ricevere eventi dall'inventario, e il suo nome è `""`.
|
||||||
|
|
||||||
Ci sono svariate mod che permettono ad altrettante mod di personalizzare l'inventario del giocatore.
|
Ci sono svariate mod che permettono ad altrettante mod di personalizzare l'inventario del giocatore.
|
||||||
La mod ufficialmente raccomandata è [Simple Fast Inventory (sfinv)](sfinv.html), ed è inclusa in Minetest Game.
|
La mod ufficialmente raccomandata è [SFINV](https://github.com/rubenwardy/sfinv/blob/master/Tutorial.md), ed è inclusa in Minetest Game.
|
||||||
|
|
||||||
### Il tuo turno
|
### Il tuo turno
|
||||||
|
|
||||||
|
@ -1,223 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "SFINV"
|
sitemap: false
|
||||||
layout: default
|
redirect_to: "https://github.com/rubenwardy/sfinv/blob/master/Tutorial.md"
|
||||||
root: ../..
|
|
||||||
idx: 4.7
|
|
||||||
description: una mod per rendere più semplice la creazione di un inventario complesso
|
|
||||||
redirect_from: /it/chapters/sfinv.html
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Introduzione <!-- omit in toc -->
|
|
||||||
|
|
||||||
Simple Fast Inventory (SFINV) è una mod presente in Minetest Game, usata per creare il [formspec](formspecs.html) del giocatore.
|
|
||||||
SFINV ha un'API che permette di aggiungere e altresì gestire le pagine mostrate.
|
|
||||||
|
|
||||||
Mentre SFINV di base mostra le pagine come finestre, le pagine sono chiamate tali in quanto è assolutamente possibile che una mod o un gioco decidano di mostrarle in un altro formato.
|
|
||||||
Per esempio, più pagine possono essere mostrate nel medesimo formspec.
|
|
||||||
|
|
||||||
- [Registrare una pagina](#registrare-una-pagina)
|
|
||||||
- [Ricevere eventi](#ricevere-eventi)
|
|
||||||
- [Condizioni per la visualizzazione](#condizioni-per-la-visualizzazione)
|
|
||||||
- [Callback on_enter e on_leave](#callback-onenter-e-onleave)
|
|
||||||
- [Aggiungere a una pagina esistente](#aggiungere-a-una-pagina-esistente)
|
|
||||||
|
|
||||||
## Registrare una pagina
|
|
||||||
|
|
||||||
SFINV fornisce la funzione chiamata `sfinv.register_page` per creare nuove pagine.
|
|
||||||
Basta chiamare la funzione con il nome che si vuole assegnare alla pagina e la sua definizione:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
sfinv.register_page("miamod:ciao", {
|
|
||||||
title = "Ciao!",
|
|
||||||
get = function(self, player, context)
|
|
||||||
return sfinv.make_formspec(player, context,
|
|
||||||
"label[0.1,0.1;Ciao mondo!]", true)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
La funzione `make_formspec` circonda il formspec con il codice di SFINV.
|
|
||||||
Il quarto parametro, attualmente impostato a `true`, determina se l'inventario del giocatore è mostrato.
|
|
||||||
|
|
||||||
Rendiamo le cose più eccitanti; segue il codice della generazione di un formspec per gli admin.
|
|
||||||
Questa finestra permetterà agli admin di cacciare o bannare i giocatori selezionandoli da una lista e premendo un pulsante.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
sfinv.register_page("mioadmin:mioadmin", {
|
|
||||||
title = "Finestra",
|
|
||||||
get = function(self, player, context)
|
|
||||||
local giocatori = {}
|
|
||||||
context.mioadmin_giocatori = giocatori
|
|
||||||
|
|
||||||
-- Usare un array per costruire un formspec è decisamente più veloce
|
|
||||||
local formspec = {
|
|
||||||
"textlist[0.1,0.1;7.8,3;lista_giocatori;"
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Aggiunge tutti i giocatori sia alla lista testuale che a quella - appunto - dei giocatori
|
|
||||||
local primo = true
|
|
||||||
for _ , giocatore in pairs(minetest.get_connected_players()) do
|
|
||||||
local nome_giocatore = giocatore:get_player_name()
|
|
||||||
giocatori[#giocatori + 1] = nome_giocatore
|
|
||||||
if not primo then
|
|
||||||
formspec[#formspec + 1] = ","
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] =
|
|
||||||
minetest.formspec_escape(nome_giocatore)
|
|
||||||
primo = false
|
|
||||||
end
|
|
||||||
formspec[#formspec + 1] = "]"
|
|
||||||
|
|
||||||
-- Aggiunge i pulsanti
|
|
||||||
formspec[#formspec + 1] = "button[0.1,3.3;2,1;caccia;Caccia]"
|
|
||||||
formspec[#formspec + 1] = "button[2.1,3.3;2,1;banna;Caccia e Banna]"
|
|
||||||
|
|
||||||
-- Avvolge il formspec nella disposizione di SFINV
|
|
||||||
-- (es: aggiunge le linguette delle finestre e lo sfondo)
|
|
||||||
return sfinv.make_formspec(player, context,
|
|
||||||
table.concat(formspec, ""), false)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Non c'è niente di nuovo in questa parte di codice; tutti i concetti sono già stati trattati o qui in alto o nei precedenti capitoli.
|
|
||||||
|
|
||||||
<figure>
|
|
||||||
<img src="{{ page.root }}//static/sfinv_admin_fs.png" alt="Pagina per gli amministratori">
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
## Ricevere eventi
|
|
||||||
|
|
||||||
Puoi ricevere eventi formspec tramite l'aggiunta della funzione `on_player_receive_fields` nella definizione SFINV.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_player_receive_fields = function(self, player, context, fields)
|
|
||||||
-- TODO: implementarlo
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
`on_player_receive_fields` funziona alla stessa maniera di `minetest.register_on_player_receive_fields`, con la differenza che viene richiesto il contesto al posto del nome del form.
|
|
||||||
Tieni a mente che gli eventi interni di SFINV, come la navigazione tra le varie finestre, vengono gestiti dentro la mod stessa, e che quindi non verranno ricevuti in questo callback.
|
|
||||||
|
|
||||||
Implementiamo ora `on_player_receive_fields` nella mod:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_player_receive_fields = function(self, player, context, fields)
|
|
||||||
-- evento della lista testuale: controlla il tipo di evento e imposta il nuovo indice se è cambiata la selezione
|
|
||||||
if fields.lista_giocatori then
|
|
||||||
local event = minetest.explode_textlist_event(fields.lista_giocatori)
|
|
||||||
if event.type == "CHG" then
|
|
||||||
context.mioadmin_sel_id = event.index
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Al premere "Caccia"
|
|
||||||
elseif fields.caccia then
|
|
||||||
local nome_giocatore =
|
|
||||||
context.myadmin_players[context.mioadmin_sel_id]
|
|
||||||
if player_name then
|
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
|
||||||
"Cacciato " .. nome_giocatore)
|
|
||||||
minetest.kick_player(nome_giocatore)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Al premere "Caccia e Banna"
|
|
||||||
elseif fields.banna then
|
|
||||||
local nome_giocatore =
|
|
||||||
context.myadmin_players[context.mioadmin_sel_id]
|
|
||||||
if player_name then
|
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
|
||||||
"Banned " .. player_name)
|
|
||||||
minetest.ban_player(nome_giocatore)
|
|
||||||
minetest.kick_player(nome_giocatore, "Banned")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
C'è, tuttavia, un problema abbastanza grande a riguardo: chiunque può cacciare o bannare i giocatori!
|
|
||||||
C'è bisogno di un modo per mostrare questa finestra solo a chi ha i privilegi `kick` e `ban`.
|
|
||||||
Fortunatamente, SFINV ci permette di farlo!
|
|
||||||
|
|
||||||
## Condizioni per la visualizzazione
|
|
||||||
|
|
||||||
Si può aggiungere una funzione `is_in_nav` nella definizione della pagina se si desidera gestire quando la pagina deve essere mostrata:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
is_in_nav = function(self, player, context)
|
|
||||||
local privs = minetest.get_player_privs(player:get_player_name())
|
|
||||||
return privs.kick or privs.ban
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
Se si ha bisogno di controllare un solo privilegio o si vuole eseguire un `and`, si bisognerebbe usare `minetest.check_player_privs()` al posto di `get_player_privs`.
|
|
||||||
|
|
||||||
Tieni a mente che `is_in_nav` viene chiamato soltanto alla generazione dell'inventario del giocatore.
|
|
||||||
Questo succede quando un giocatore entra in gioco, si muove tra le finestre, o una mod richiede a SFINV di rigenerare l'inventario.
|
|
||||||
|
|
||||||
Ciò significa che hai bisogno di richiedere manualmente la rigenerazione del formspec dell'inventario per ogni evento che potrebbe cambiare il risultato ti `is_in_nav`.
|
|
||||||
Nel nostro caso, abbiamo bisogno di farlo ogni volta che i permessi `kick` o `ban` vengono assegnati/revocati a un giocatore:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local function al_cambio_privilegi(nome_target, nome_garante, priv)
|
|
||||||
if priv ~= "kick" and priv ~= "ban" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local giocatore = minetest.get_player_by_name(nome_target)
|
|
||||||
if not giocatore then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local contesto = sfinv.get_or_create_context(giocatore)
|
|
||||||
if contesto.page ~= "mioadmin:mioadmin" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
sfinv.set_player_inventory_formspec(giocatore, contesto)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_priv_grant(al_cambio_privilegi)
|
|
||||||
minetest.register_on_priv_revoke(al_cambio_privilegi)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Callback on_enter e on_leave
|
|
||||||
|
|
||||||
Un giocatore *entra* in una finestra quando la finestra è selezionata e *esce* dalla finestra quando un'altra finestra è prossima a essere selezionata.
|
|
||||||
Attenzione che è possibile selezionare più pagine alla volta se viene usata un tema personalizzato.
|
|
||||||
|
|
||||||
Si tenga conto, poi, che questi eventi potrebbero non essere innescati dal giocatore, in quanto potrebbe addirittura non avere un formspec aperto in quel momento.
|
|
||||||
Per esempio, `on_enter` viene chiamato dalla pagina principale anche quando un giocatore entra in gioco, ancor prima che apri l'inventario.
|
|
||||||
|
|
||||||
Infine, non è possibile annullare il cambio pagina, in quanto potrebbe potenzialmente confondere il giocatore.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
on_enter = function(self, player, context)
|
|
||||||
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_leave = function(self, player, context)
|
|
||||||
|
|
||||||
end,
|
|
||||||
```
|
|
||||||
|
|
||||||
## Aggiungere a una pagina esistente
|
|
||||||
|
|
||||||
Per aggiungere contenuti a una pagina che già esiste, avrai bisogno di sovrascrivere la pagina e modificare il formspec che viene ritornato:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local vecchia_funzione = sfinv.registered_pages["sfinv:crafting"].get
|
|
||||||
sfinv.override_page("sfinv:crafting", {
|
|
||||||
get = function(self, player, context, ...)
|
|
||||||
local ret = vecchia_funzione(self, player, context, ...)
|
|
||||||
|
|
||||||
if type(ret) == "table" then
|
|
||||||
ret.formspec = ret.formspec .. "label[0,0;Ciao]"
|
|
||||||
else
|
|
||||||
-- Retrocompatibilità
|
|
||||||
ret = ret .. "label[0,0;Ciao]"
|
|
||||||
end
|
|
||||||
|
|
||||||
return ret
|
|
||||||
end
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
@ -8,11 +8,12 @@ layout: base
|
|||||||
|
|
||||||
{% if language == "_it" %}
|
{% if language == "_it" %}
|
||||||
{% assign language = "it" %}
|
{% assign language = "it" %}
|
||||||
{% assign links = site.it | sort: "idx" %}
|
{% assign links = site.it %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% assign language = "en" %}
|
{% assign language = "en" %}
|
||||||
{% assign links = site.en | sort: "idx" %}
|
{% assign links = site.en %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% assign links = links | where_exp: "item", "item.sitemap != false" | sort: "idx" %}
|
||||||
|
|
||||||
{% assign num = 0 %}
|
{% assign num = 0 %}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user