GUI
Visão geral
O GUI transforma uma única entry do TypeWriter, o Open GUI, em um menu de inventário completo. Você escolhe o tipo de contêiner (um baú, uma bigorna, uma janela de comerciante, um livro escrito...), escreve um título em MiniMessage e depois descreve o conteúdo como uma árvore de layouts armazenada no layoutPool da entry. Cada layout posiciona itens: um material, um nome, um pouco de lore e o que acontece quando um jogador clica nele.
Tudo é editado no painel web: não há arquivos de menu para escrever à mão. Um menu é aberto como qualquer outra action, a partir de uma etapa de quest, de um diálogo de NPC, de um evento de comando ou de outro menu. Os cliques executam comandos de console, disparam outras entries e modificam facts, então um menu é só mais uma forma de conduzir suas páginas do TypeWriter.
O GUI também é a base das outras extensões de menu da BTC. Shops e Quest Codex não trazem uma janela própria: elas colocam itens marcadores em um layout de open_gui e a extensão os preenche com produtos ou quests.
Recursos
- Dez layouts —
simple,flex,paginated,scrollable,frame,composite,book,merchant,storageeleaderboard. - 24 tipos de contêiner — baús de 9 a 54 slots, além de bigorna, mesa de encantamento, mesa de ferraria, cortador de pedra, pedra de amolar, tear, mesa de cartografia, comerciante, livro, funil, fornalhas e mais.
- MiniMessage em todo lugar — cores, gradientes e placeholders do PlaceholderAPI em títulos, nomes de itens e lore.
- Ações de clique por tipo de clique — clique esquerdo, direito, com shift, do meio, duplo, teclas numéricas, soltar e troca com a mão secundária, cada um com seus próprios comandos e triggers.
- Permissões de slot — oculte um slot com
viewPermissionou deixe-o visível, mas inerte, comclickPermission. - Repetição de slots — preencha uma linha ou um bloco com
count,direction,gaperepeatYem vez de copiar itens. - Views e abas — uma única estrutura de menu, várias telas, com título em breadcrumb e abas que se acendem.
- Armazenamento persistente — slots que guardam seus itens por jogador ou por grupo, com cotas, placeholders e drop opcional ao fechar.
- Leaderboards — classifique jogadores, mundos ou grupos por um ou mais facts, inclusive jogadores offline, ou mostre as linhas fornecidas por outra extensão pelo campo
source(as estatísticas do Dungeon, por exemplo). - Inventário estendido — transforme o inventário do próprio jogador em quatro linhas extras do menu, para uma tela de dez linhas.
Instalação
- Instale o TypeWriter em um servidor Paper ou Folia. O PacketEvents, que o TypeWriter já exige, precisa estar presente.
- Baixe o JAR nos GitHub releases do GUI (o botão no painel de resumo acima).
- Coloque-o em
plugins/Typewriter/extensions/e reinicie o servidor. - Opcional: instale o CraftEngine se seus títulos usam as tags
<image>ou<shift>para desenhar fundos personalizados.
Instale o GUI antes das extensões que dependem dele, como Shops e Quest Codex.
A versão pública do GUI não inclui um editor de menus independente nem seu servidor web: os menus são editados no painel web do TypeWriter. A versão traz apenas uma verificação de inicialização que lê suas entries open_gui publicadas e informa menus quebrados no console (veja Solução de problemas).
Primeiros passos
Construa um pequeno menu de três botões:
- No painel web, abra uma página de sequence e adicione uma entry Open GUI. Dê a ela o nome
main_menu. - Defina
guiTypecomoCUSTOM,sizecomoSIZE_27etitlecomo<gold>Main menu. - Em
layoutPool, adicione um layout do tiposimple, dê a ele oidmaine digitemainemmainLayoutId. - Em
itemsdo layout, adicione um item emx4,y1. Escolha umDIAMONDemitem, definadisplayNamecomo<aqua>Rewardse adicione uma linha delore<gray>Click to claim. - Em
interactionList, adicione uma interaction comtypeLEFT_CLICK. Adicione um comando de console comogive %player% diamond 1emcommands, ou vincule uma entry emtriggers. AtivecloseMenupara fechar o menu após o clique. - Adicione um segundo item
simplecomcount9,directionrighte um painel de vidro cinza para desenhar uma linha de borda. Defina seudisplayNamecomo um único espaço. - Vincule a entry Open GUI a algo que a dispare, por exemplo o trigger de uma opção de diálogo ou um evento de comando, e depois clique em Publish.
Faça um único layout simple funcionar no jogo antes de adicionar camadas frame, scrollable ou paginated. Cada layout é endereçado pelo seu id, então um mainLayoutId digitado errado é a primeira coisa a verificar quando um menu abre vazio.
Como funciona
Quando a action é disparada, a extensão monta a árvore de layouts para aquele jogador (os criteria e as permissões são avaliados neste momento), registra uma sessão de menu e exibe o inventário. Cada clique é resolvido no slot daquela posição e então executa a interaction correspondente. A sessão lembra dos menus anteriores, então gui:back volta ao menu de onde o jogador veio.
Menus
Tipos de contêiner
guiType seleciona a janela. CUSTOM é um inventário simples, semelhante a um baú, cuja altura você escolhe com size. size só se aplica a CUSTOM e tem seis linhas por padrão; os outros tipos usam o tamanho vanilla de sua janela.
guiType | Janela |
|---|---|
CUSTOM, CHEST, ENDER_CHEST, BARREL, SHULKER_BOX | Grades no estilo de baú. Para CUSTOM, size é SIZE_9, SIZE_18, SIZE_27, SIZE_36, SIZE_45 ou SIZE_54. |
HOPPER, DISPENSER, DROPPER | Contêineres pequenos de tamanho fixo. |
FURNACE, BLAST_FURNACE, SMOKER, BREWING_STAND, BEACON | Janelas de máquinas. |
CRAFTING_TABLE, ENCHANTING_TABLE, ANVIL, SMITHING_TABLE, GRINDSTONE, LOOM, CARTOGRAPHY_TABLE, STONECUTTER | Bancadas vanilla. Sem layout, comportam-se como a tela vanilla; o GUI apenas gerencia a abertura e o fechamento. |
MERCHANT, VILLAGER_TRADE | A janela de troca de aldeões, preenchida por um layout merchant. |
BOOK | Um livro escrito, preenchido por um layout book. |
Layouts
Cada layout é uma entrada nomeada do layoutPool. O indicado em mainLayoutId é a raiz; os outros são alcançados por referências (filhos de composite, innerId de scrollable, layoutId de frame).
| Layout | Use para | Campos principais |
|---|---|---|
simple | Botões fixos e decoração em posições x/y. | items |
flex | Itens dispostos automaticamente em linhas. | justifyContent (START, CENTER, END, SPACE_BETWEEN), alignItems, wrap, virtualHeight |
paginated | Uma lista longa dividida em páginas. | itemsPerPage, slots, items, navigationButtons (NEXT, PREVIOUS, BACK, INDICATOR) |
scrollable | Conteúdo mais alto ou mais largo que a janela. | innerId, virtualWidth, virtualHeight, buttons (direction, step), showDefaultButtons, defaultStep |
frame | Vários retângulos independentes, por exemplo abas, conteúdo e rodapé. | frames (id, x, y, width, height, layoutId) |
composite | Empilhar camadas: fundo, conteúdo, botões. | children (ids de layouts; os filhos posteriores são desenhados por cima) |
book | As páginas de um livro escrito. | pages (MiniMessage) |
merchant | Trocas de aldeões com itens personalizados. | trades (result, costOne, costTwo, maxUses, criteria) |
storage | Slots persistentes apoiados por um artifact GUI Storage. | entry, groupKey, slots |
leaderboard | Linhas de ranking com páginas, a partir de facts ou da source de outra extensão. | leaderboard, x, y, width, height, previousButton, nextButton |
Um layout book ou merchant só funciona como layout principal, e guiType é substituído pela janela correspondente. Um layout scrollable recebe setas padrão enquanto showDefaultButtons estiver ativado (o padrão): uma para cada direção sem entrada em buttons, veja Layouts, frames e slots.
Veja Layouts, frames e slots para um passo a passo detalhado de cada layout.
Itens e slots
Cada item de um layout é uma descrição de slot com os mesmos campos:
| Campo | Função |
|---|---|
item | O item a exibir. Se vazio, o slot mostra o item que o jogador segura na mão principal. |
displayName, lore | Texto MiniMessage com suporte ao PlaceholderAPI. Os nomes são exibidos sem itálico por padrão; adicione <italic> se quiser itálico. Um displayName vazio mantém o nome do item em vez de substituí-lo por um nome vazio. |
x, y | Coluna de 0 a 8 e linha a partir de 0 no topo. |
rollPerSlot | Para um item repetido em vários slots cujo item é aleatório: desativado (padrão), sorteia uma vez e todos os slots mostram esse resultado; ativado, cada slot sorteia por conta própria ao abrir o menu. O resultado é mantido enquanto o menu ficar aberto, a menos que liveItem esteja ativado. |
liveItem | Desativado (padrão): o item é sorteado ao abrir o menu e mantido durante toda a sessão; ao atualizar, só o nome e a descrição acompanham. Ativado: o item é avaliado de novo a cada atualização, então um item aleatório é sorteado outra vez a cada vez. Com rollPerSlot ativado, cada slot repetido sorteia por conta própria a cada atualização; sem ele, todos os slots repetidos compartilham um sorteio por atualização. Um nome vazio continua sendo ignorado. |
count, direction, gap, repeatY | Repetição de slots, veja abaixo. |
criteria | O slot não é desenhado para os jogadores que não correspondem. |
viewPermission | Permissão necessária para ver o slot. |
clickPermission | Permissão necessária para usar o slot; sem ela, o slot é desenhado, mas fica inerte. |
allowPickup, isGhost | Define se o item pode ser retirado do menu. Ambos vêm desativados por padrão; itens fantasma podem ser clicados, mas nunca movidos nem copiados. |
cooldownTicks | Ticks antes que o mesmo slot possa ser clicado novamente. |
interactionList, triggers, modifiers | O que um clique faz. |
input | Abre um diálogo de entrada de texto ao clicar. |
storageId | Transforma o slot em um slot de armazenamento persistente do storagePool. |
buttonType, buttonPrefix | Marca o slot como um botão fornecido por outra extensão. |
animation | Move o slot para uma posição de destino ao longo de uma duração em milissegundos quando o menu abre. |
Repetição de slots. count repete um item ao longo de direction (right, left, down, up). gap é um passo, não um espaçamento: 1 é adjacente, 2 deixa um slot vazio entre as cópias e 0 se comporta como 1. repeatY repete a linha inteira no eixo perpendicular. Sem um direction, count, gap e repeatY são ignorados e um único slot é posicionado. Esses campos contam slots, nunca o tamanho da pilha do item.
Sobreposições. Quando dois slots compartilham uma célula, aquele que faz alguma coisa (uma ação de clique, uma tag, um slot de armazenamento) prevalece sobre um puramente decorativo, independentemente da ordem. Entre dois do mesmo tipo, prevalece o último declarado. Um aviso com o nome da célula é registrado uma única vez.
Ações de clique
interactionList associa um tipo de clique a comandos e triggers. Os tipos disponíveis são LEFT_CLICK, RIGHT_CLICK, SHIFT_LEFT_CLICK, SHIFT_RIGHT_CLICK, MIDDLE_CLICK, DOUBLE_CLICK, NUMBER_KEY_1 a NUMBER_KEY_9, DROP, DROP_ALL e SWAP_OFFHAND.
commandssão executados pelo console.%player%é substituído pelo nome do jogador, e os placeholders do PlaceholderAPI são resolvidos primeiro.triggersdisparam entries do TypeWriter para o jogador. Os própriostriggersemodifiersdo slot são disparados a cada clique esquerdo ou direito, ou sempre que uma interaction específica corresponde.closeMenufecha a janela após a ação.executeReturnvolta ao menu anterior.
Os comandos que começam com gui: são tratados pelo próprio GUI:
| Comando | Efeito |
|---|---|
gui:close | Fecha o menu. |
gui:back | Reabre o menu anterior da sessão. |
gui:open <entry_id> ou gui:action <entry_id> | Dispara outra entry, normalmente outro Open GUI. |
gui:view <view_id> | Muda para outra view sem fechar o inventário. |
gui:page <delta> [layout_id] | Avança um layout paginado ou de leaderboard essa quantidade de páginas. |
gui:scroll <dx> <dy> [layout_id] | Rola um layout scrollable. |
gui:refresh | Redesenha o menu agora. |
gui:sound <sound_key> | Toca um som para o jogador. |
Abrir, voltar e fechar
Um Open GUI aberto a partir de outro menu é empilhado no histórico da sessão, então gui:back ou executeReturn volta a ele. Fechar com Esc encerra a sessão. Abrir um layout de livro encerra antes a sessão atual.
Defina audio para tocar sons ao abrir, fechar, rolar e clicar. Defina autoRefreshTicks para redesenhar o menu a cada N ticks enquanto ele estiver aberto, o que faz os placeholders em nomes e lore se atualizarem como um contador ou um cronômetro.
Views, abas e herança
views transformam um único open_gui em várias telas que compartilham a mesma estrutura. Um frame cujo layoutId é @view é preenchido com o layout da view ativa: primeiro o mapeamento explícito frames da view, depois o layout chamado <view id>_<frame id> e, por fim, as mesmas buscas no parentId da view. Marque um item de aba com buttonPrefix view: e buttonType definido como o id da view, e ele muda de view ao ser clicado e se acende enquanto estiver ativo. O título da view aceita {breadcrumb}, {view} e {root}.
baseMenuId aponta para outro Open GUI e mescla seu layoutPool, views e storagePool sob os seus: um layout com o mesmo id substitui o herdado. Detalhes em Views, abas e herança.
Slots de armazenamento
Um artifact GUI Storage guarda os itens, por jogador ou por grupo. Declare configurações reutilizáveis no storagePool da entry e depois dê a um item um storageId, ou use um layout storage. Os nomes e a lore de itens de um slot de armazenamento aceitam {stored_name}, {stored_amount} e {stored_max}. {score_raw} e {value_<key>} também existem para as linhas de um leaderboard com source.
Atalhos de clique padrão, que você pode alterar em GUI Global Settings:
| Ação | Clique padrão |
|---|---|
| Colocar um item do cursor | Clique esquerdo |
| Colocar a pilha inteira do cursor | Shift + clique esquerdo |
| Retirar um item | Clique direito |
| Retirar tudo | Clique esquerdo |
| Retirar uma pilha | Shift + clique direito |
| Preencher a partir do inventário | Trocar com a mão secundária (F) |
| Soltar tudo no chão | Soltar (Q) |
dropOnClose solta aos pés do jogador o que ainda está armazenado quando o menu realmente fecha, com Esc ou ao desconectar, mas não quando o jogador passa para outro menu.
Inventário estendido
extendToPlayerInventory mostra os 36 slots do próprio jogador como quatro linhas extras, para uma tela de dez linhas (y de 0 a 9). Funciona apenas no cliente: o inventário real nunca é modificado e é restaurado quando o menu fecha, e não é possível pegar itens das linhas de baixo. Exige guiType CUSTOM com size SIZE_54. Um layout raiz cujo id termina em _extended o ativa por conta própria.
Configuração
O GUI não tem arquivo de configuração. Duas entries de manifest opcionais o ajustam:
- GUI Extension Configuration ativa o log de
debuge a opçãohideVanillaItemStats, ativada por padrão, que oculta as linhas de dano de ataque, durabilidade e encantamentos nos botões do menu. - GUI Global Settings define os atalhos de clique do armazenamento e os itens conectores da árvore de habilidades.
Placeholders
| Placeholder | Retorna |
|---|---|
%typewriter_gui_storage_amount_<entry_id>_<slot_index>% | Número de itens armazenados para o jogador em uma entry GUI Storage, 0 se vazio. |
%typewriter_gui_storage_has_<entry_id>_<slot_index>% | true quando o slot contém um item, caso contrário false. |
<slot_index> é y * 9 + x do slot de armazenamento. Esses placeholders sempre leem o armazenamento do próprio jogador, nunca um armazenamento de grupo compartilhado.
Dentro dos menus, os seguintes tokens são substituídos pela extensão: {stored_name}, {stored_amount}, {stored_max} (slots de armazenamento), {page}, {next_page}, {prev_page}, {total_pages} e {page_indicator} (o botão INDICATOR de um layout paginado), e {rank}, {name}, {score}, {group}, {world} e {score_<fact_id>} (linhas de leaderboard).
Entries
6 entradas, geradas a partir do código-fonte da extensão.
Ações1
- Open GUIOpen a GUI for the player
Artefatos2
- GUI Leaderboard PopulationOffline population data for GUI leaderboards
- GUI StoragePersistent storage artifact for GUI storage slots
Manifestos3
- GUI ConfigGUI Extension Configuration
- GUI LeaderboardGUI leaderboard backed by Typewriter facts
- GUI SettingsGUI Global Settings
Solução de problemas
O menu abre vazio. mainLayoutId está em branco ou não corresponde a nenhum id de layout em layoutPool (os ids diferenciam maiúsculas de minúsculas). Ao usar baseMenuId, um mainLayoutId em branco recorre ao do pai. A verificação de inicialização informa no console um layout principal não resolvido.
Um slot está faltando e o console diz "falls outside the grid". O item caiu em um x ou y negativo, ou além da coluna 8. Isso costuma vir de um count grande demais, que conta slots. O log informa o layout e as coordenadas rejeitadas.
O console diz "Slot overlap ... gap". Dois slots compartilham uma célula. gap é um passo: 1 posiciona slots adjacentes e 2 deixa um slot vazio entre cada um, então quem lê gap: 1 como "um espaço" acaba com cópias sobre as vizinhas umas das outras. Altere gap ou mova um dos slots.
Um slot é visível para admins, mas não para jogadores. viewPermission indica uma permissão que ninguém além dos operadores possui. Valores em branco são ignorados, mas um erro de digitação é um node real, restrito a operadores. A mesma regra vale para o viewPermission de uma view.
Um botão aparece, mas não faz nada. Verifique clickPermission, depois cooldownTicks e depois criteria. Se o slot tem um buttonType, seu buttonPrefix deve corresponder à extensão que o fornece; uma tag não reivindicada mantém seu próprio interactionList, mas nada além disso. Os comandos são executados pelo console, então um comando que exige um jogador como remetente falha silenciosamente.
O conteúdo rolável não se move. Verifique se o conteúdo é maior que a janela (virtualWidth e virtualHeight): uma seta só aparece enquanto houver algo para rolar na sua direção. Com showDefaultButtons desativado e sem buttons, não há nenhuma seta. Uma seta padrão também cede o lugar quando a sua célula já contém um item de conteúdo, um botão ou uma decoração: nada é registrado no console, então mova-a com scrollArrows em GUI Settings ou adicione seus próprios buttons com um direction e um step, fora da área rolada.
O leaderboard lista apenas jogadores online. Vincule um artifact GUI Leaderboard Population no campo population do leaderboard para manter os últimos valores conhecidos dos jogadores offline.
O menu estendido não mostra dez linhas. extendToPlayerInventory exige guiType CUSTOM e size SIZE_54.
Extensões relacionadas
- Shops — menus de loja construídos sobre layouts do GUI e o marcador
shop_button:. - Quest Codex — o menu do registro de quests, construído sobre a mesma base
open_gui.