Pular para o conteúdo principal

GUI

Menus de inventário criados no painel web: layouts, itens, ações de clique, armazenamento e rankings.

Gratuitasv0.20Menus e visuais

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, storage e leaderboard.
  • 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 viewPermission ou deixe-o visível, mas inerte, com clickPermission.
  • Repetição de slots — preencha uma linha ou um bloco com count, direction, gap e repeatY em 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​

  1. Instale o TypeWriter em um servidor Paper ou Folia. O PacketEvents, que o TypeWriter já exige, precisa estar presente.
  2. Baixe o JAR nos GitHub releases do GUI (o botão no painel de resumo acima).
  3. Coloque-o em plugins/Typewriter/extensions/ e reinicie o servidor.
  4. 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.

Editor web

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:

  1. No painel web, abra uma página de sequence e adicione uma entry Open GUI. Dê a ela o nome main_menu.
  2. Defina guiType como CUSTOM, size como SIZE_27 e title como <gold>Main menu.
  3. Em layoutPool, adicione um layout do tipo simple, dê a ele o id main e digite main em mainLayoutId.
  4. Em items do layout, adicione um item em x 4, y 1. Escolha um DIAMOND em item, defina displayName como <aqua>Rewards e adicione uma linha de lore <gray>Click to claim.
  5. Em interactionList, adicione uma interaction com type LEFT_CLICK. Adicione um comando de console como give %player% diamond 1 em commands, ou vincule uma entry em triggers. Ative closeMenu para fechar o menu após o clique.
  6. Adicione um segundo item simple com count 9, direction right e um painel de vidro cinza para desenhar uma linha de borda. Defina seu displayName como um único espaço.
  7. 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.
Comece simples

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.

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.

guiTypeJanela
CUSTOM, CHEST, ENDER_CHEST, BARREL, SHULKER_BOXGrades no estilo de baú. Para CUSTOM, size é SIZE_9, SIZE_18, SIZE_27, SIZE_36, SIZE_45 ou SIZE_54.
HOPPER, DISPENSER, DROPPERContêineres pequenos de tamanho fixo.
FURNACE, BLAST_FURNACE, SMOKER, BREWING_STAND, BEACONJanelas de máquinas.
CRAFTING_TABLE, ENCHANTING_TABLE, ANVIL, SMITHING_TABLE, GRINDSTONE, LOOM, CARTOGRAPHY_TABLE, STONECUTTERBancadas vanilla. Sem layout, comportam-se como a tela vanilla; o GUI apenas gerencia a abertura e o fechamento.
MERCHANT, VILLAGER_TRADEA janela de troca de aldeões, preenchida por um layout merchant.
BOOKUm 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).

LayoutUse paraCampos principais
simpleBotões fixos e decoração em posições x/y.items
flexItens dispostos automaticamente em linhas.justifyContent (START, CENTER, END, SPACE_BETWEEN), alignItems, wrap, virtualHeight
paginatedUma lista longa dividida em páginas.itemsPerPage, slots, items, navigationButtons (NEXT, PREVIOUS, BACK, INDICATOR)
scrollableConteúdo mais alto ou mais largo que a janela.innerId, virtualWidth, virtualHeight, buttons (direction, step), showDefaultButtons, defaultStep
frameVários retângulos independentes, por exemplo abas, conteúdo e rodapé.frames (id, x, y, width, height, layoutId)
compositeEmpilhar camadas: fundo, conteúdo, botões.children (ids de layouts; os filhos posteriores são desenhados por cima)
bookAs páginas de um livro escrito.pages (MiniMessage)
merchantTrocas de aldeões com itens personalizados.trades (result, costOne, costTwo, maxUses, criteria)
storageSlots persistentes apoiados por um artifact GUI Storage.entry, groupKey, slots
leaderboardLinhas 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:

CampoFunção
itemO item a exibir. Se vazio, o slot mostra o item que o jogador segura na mão principal.
displayName, loreTexto 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, yColuna de 0 a 8 e linha a partir de 0 no topo.
rollPerSlotPara 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.
liveItemDesativado (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, repeatYRepetição de slots, veja abaixo.
criteriaO slot não é desenhado para os jogadores que não correspondem.
viewPermissionPermissão necessária para ver o slot.
clickPermissionPermissão necessária para usar o slot; sem ela, o slot é desenhado, mas fica inerte.
allowPickup, isGhostDefine 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.
cooldownTicksTicks antes que o mesmo slot possa ser clicado novamente.
interactionList, triggers, modifiersO que um clique faz.
inputAbre um diálogo de entrada de texto ao clicar.
storageIdTransforma o slot em um slot de armazenamento persistente do storagePool.
buttonType, buttonPrefixMarca o slot como um botão fornecido por outra extensão.
animationMove 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.

  • commands são executados pelo console. %player% é substituído pelo nome do jogador, e os placeholders do PlaceholderAPI são resolvidos primeiro.
  • triggers disparam entries do TypeWriter para o jogador. Os próprios triggers e modifiers do slot são disparados a cada clique esquerdo ou direito, ou sempre que uma interaction específica corresponde.
  • closeMenu fecha a janela após a ação. executeReturn volta ao menu anterior.

Os comandos que começam com gui: são tratados pelo próprio GUI:

ComandoEfeito
gui:closeFecha o menu.
gui:backReabre 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:refreshRedesenha 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çãoClique padrão
Colocar um item do cursorClique esquerdo
Colocar a pilha inteira do cursorShift + clique esquerdo
Retirar um itemClique direito
Retirar tudoClique esquerdo
Retirar uma pilhaShift + clique direito
Preencher a partir do inventárioTrocar com a mão secundária (F)
Soltar tudo no chãoSoltar (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 debug e a opção hideVanillaItemStats, 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​

PlaceholderRetorna
%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
Artefatos2
Manifestos3

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.