Zum Hauptinhalt springen

GUI

Inventarmenüs, die im Webpanel gebaut werden: Layouts, Items, Klickaktionen, Speicher und Bestenlisten.

Kostenlosv0.20Menüs & Visuelles
BenötigtTypeWriter0.9PacketEventsCraftEngineoptional

Überblick​

GUI macht aus einem einzigen TypeWriter-Entry, Open GUI, ein vollständiges Inventarmenü. Du wählst den Container-Typ (eine Truhe, einen Amboss, ein Händlerfenster, ein beschriebenes Buch ...), schreibst einen Titel in MiniMessage und beschreibst dann den Inhalt als Baum aus Layouts, der im layoutPool des Entrys gespeichert ist. Jedes Layout platziert Items: ein Material, einen Namen, etwas Lore und was passiert, wenn ein Spieler darauf klickt.

Alles wird im Web-Panel bearbeitet: Es gibt keine Menüdateien, die du von Hand schreiben musst. Ein Menü wird wie jede andere Action geöffnet, aus einem Quest-Schritt, einem NPC-Dialog, einem Befehls-Event oder einem anderen Menü. Klicks führen Konsolenbefehle aus, lösen andere Entries aus und ändern Facts, ein Menü ist also nur eine weitere Möglichkeit, deine TypeWriter-Seiten zu steuern.

GUI ist außerdem die Grundlage der anderen BTC-Menü-Erweiterungen. Shops und Quest Codex bringen kein eigenes Fenster mit: Sie platzieren Marker-Items in einem open_gui-Layout, und die Erweiterung füllt sie mit Produkten oder Quests.

Funktionen​

  • Zehn Layouts — simple, flex, paginated, scrollable, frame, composite, book, merchant, storage und leaderboard.
  • 24 Container-Typen — Truhengrößen von 9 bis 54 Slots, außerdem Amboss, Zaubertisch, Schmiedetisch, Steinsäge, Schleifstein, Webstuhl, Kartentisch, Händler, Buch, Trichter, Öfen und mehr.
  • MiniMessage überall — Farben, Farbverläufe und PlaceholderAPI-Platzhalter in Titeln, Item-Namen und Lore.
  • Klick-Aktionen pro Klicktyp — Links-, Rechts-, Shift-, Mittel- und Doppelklick, Zahlentasten, Wegwerfen und Zweithand-Tausch, jeweils mit eigenen Befehlen und Triggern.
  • Slot-Berechtigungen — blende einen Slot mit viewPermission aus oder lass ihn mit clickPermission sichtbar, aber wirkungslos.
  • Slot-Wiederholung — fülle eine Reihe oder einen Block mit count, direction, gap und repeatY, statt Items zu kopieren.
  • Views und Tabs — eine Menühülle, mehrere Bildschirme, mit Breadcrumb-Titel und Tabs, die aufleuchten.
  • Persistenter Speicher — Slots, die ihre Items pro Spieler oder pro Gruppe behalten, mit Kontingenten, Platzhaltern und optionalem Fallenlassen beim Schließen.
  • Bestenlisten — Ranglisten für Spieler, Welten oder Gruppen anhand eines oder mehrerer Facts, auch für Offline-Spieler, oder die Zeilen, die eine andere Erweiterung über das Feld source liefert (zum Beispiel die Statistiken von Dungeon).
  • Erweitertes Inventar — verwandle das eigene Inventar des Spielers in vier zusätzliche Menüreihen für eine Zeichenfläche mit zehn Reihen.

Installation​

  1. Installiere TypeWriter auf einem Paper- oder Folia-Server. PacketEvents, das TypeWriter ohnehin voraussetzt, muss vorhanden sein.
  2. Lade die JAR von den GUI-GitHub-Releases herunter (der Button im Übersichtsfeld oben).
  3. Lege sie in plugins/Typewriter/extensions/ ab und starte den Server neu.
  4. Optional: Installiere CraftEngine, wenn deine Titel <image>- oder <shift>-Tags nutzen, um eigene Hintergründe zu zeichnen.

Installiere GUI vor den Erweiterungen, die darauf aufbauen, wie Shops und Quest Codex.

Web-Editor

Das öffentliche GUI-Release enthält weder einen eigenständigen Menü-Editor noch dessen Webserver: Menüs werden im TypeWriter-Web-Panel bearbeitet. Das Release liefert nur eine Startprüfung mit, die deine veröffentlichten open_gui-Entries liest und fehlerhafte Menüs in der Konsole meldet (siehe Fehlerbehebung).

Erste Schritte​

So baust du ein kleines Menü mit drei Buttons:

  1. Öffne im Web-Panel eine Sequence-Seite und füge einen Open GUI-Entry hinzu. Nenne ihn main_menu.
  2. Setze guiType auf CUSTOM, size auf SIZE_27 und title auf <gold>Main menu.
  3. Füge in layoutPool ein Layout vom Typ simple hinzu, gib ihm die id main und trage dann main in mainLayoutId ein.
  4. Füge in den items des Layouts ein Item bei x 4, y 1 hinzu. Wähle in item einen DIAMOND, setze displayName auf <aqua>Rewards und füge eine lore-Zeile <gray>Click to claim hinzu.
  5. Füge in interactionList eine Interaction mit type LEFT_CLICK hinzu. Trage in commands einen Konsolenbefehl wie give %player% diamond 1 ein oder verknüpfe einen Entry in triggers. Aktiviere closeMenu, um das Menü nach dem Klick zu schließen.
  6. Füge ein zweites simple-Item mit count 9, direction right und einer grauen gefärbten Glasscheibe hinzu, um eine Rahmenreihe zu zeichnen. Setze dessen displayName auf ein einzelnes Leerzeichen.
  7. Verknüpfe den Open-GUI-Entry mit etwas, das ihn auslöst, zum Beispiel dem Trigger einer Dialogoption oder einem Befehls-Event, und klicke dann auf Publish.
Einfach anfangen

Bring ein einzelnes simple-Layout im Spiel zum Laufen, bevor du frame-, scrollable- oder paginated-Ebenen hinzufügst. Jedes Layout wird über seine id angesprochen, ein Tippfehler in mainLayoutId ist also das Erste, was du prüfen solltest, wenn ein Menü leer öffnet.

So funktioniert es​

Wird die Action ausgelöst, baut die Erweiterung den Layout-Baum für diesen Spieler auf (Criteria und Berechtigungen werden in diesem Moment ausgewertet), registriert eine Menü-Session und zeigt das Inventar an. Jeder Klick wird dem Slot an dieser Position zugeordnet und führt dann die passende Interaction aus. Die Session merkt sich vorherige Menüs, sodass gui:back zu dem Menü zurückführt, aus dem der Spieler kam.

Menüs​

Container-Typen​

guiType wählt das Fenster. CUSTOM ist ein einfaches truhenartiges Inventar, dessen Höhe du mit size festlegst. size gilt nur für CUSTOM und ist standardmäßig sechs Reihen groß; die anderen Typen nutzen die Vanilla-Größe ihres Fensters.

guiTypeFenster
CUSTOM, CHEST, ENDER_CHEST, BARREL, SHULKER_BOXRaster im Truhenstil. Bei CUSTOM ist size SIZE_9, SIZE_18, SIZE_27, SIZE_36, SIZE_45 oder SIZE_54.
HOPPER, DISPENSER, DROPPERKleine Container mit fester Größe.
FURNACE, BLAST_FURNACE, SMOKER, BREWING_STAND, BEACONMaschinenfenster.
CRAFTING_TABLE, ENCHANTING_TABLE, ANVIL, SMITHING_TABLE, GRINDSTONE, LOOM, CARTOGRAPHY_TABLE, STONECUTTERVanilla-Werkbänke. Ohne Layout verhalten sie sich wie der Vanilla-Bildschirm; GUI verwaltet nur das Öffnen und Schließen.
MERCHANT, VILLAGER_TRADEDas Dorfbewohner-Handelsfenster, gefüllt von einem merchant-Layout.
BOOKEin beschriebenes Buch, gefüllt von einem book-Layout.

Layouts​

Jedes Layout ist ein benannter Eintrag des layoutPool. Das in mainLayoutId genannte ist die Wurzel; die anderen werden über Verweise erreicht (composite-Kinder, innerId eines scrollable, layoutId eines frame).

LayoutVerwendungWichtige Felder
simpleFeste Buttons und Dekoration an x/y-Positionen.items
flexAutomatisch in Reihen angeordnete Items.justifyContent (START, CENTER, END, SPACE_BETWEEN), alignItems, wrap, virtualHeight
paginatedEine lange Liste, in Seiten aufgeteilt.itemsPerPage, slots, items, navigationButtons (NEXT, PREVIOUS, BACK, INDICATOR)
scrollableInhalt, der höher oder breiter ist als das Fenster.innerId, virtualWidth, virtualHeight, buttons (direction, step), showDefaultButtons, defaultStep
frameMehrere unabhängige Rechtecke, zum Beispiel Tabs, Inhalt und ein Footer.frames (id, x, y, width, height, layoutId)
compositeGestapelte Ebenen: Hintergrund, Inhalt, Buttons.children (Layout-IDs, spätere Kinder werden oben gezeichnet)
bookDie Seiten eines beschriebenen Buchs.pages (MiniMessage)
merchantDorfbewohner-Handel mit eigenen Items.trades (result, costOne, costTwo, maxUses, criteria)
storagePersistente Slots, gestützt auf ein GUI Storage-Artifact.entry, groupKey, slots
leaderboardRangzeilen mit Seiten, aus Facts oder aus der source einer anderen Erweiterung.leaderboard, x, y, width, height, previousButton, nextButton

Ein book- oder merchant-Layout funktioniert nur als Hauptlayout, und guiType wird auf das passende Fenster überschrieben. Ein scrollable-Layout erhält Standardpfeile, solange showDefaultButtons aktiv ist (Standard): einen für jede Richtung ohne Eintrag in buttons, siehe Layouts, Frames und Slots.

Eine ausführliche Erklärung jedes Layouts findest du unter Layouts, Frames und Slots.

Items und Slots​

Jedes Item eines Layouts ist eine Slot-Beschreibung mit denselben Feldern:

FeldAufgabe
itemDas anzuzeigende Item. Bleibt es leer, zeigt der Slot das Item, das der Spieler in der Haupthand hält.
displayName, loreMiniMessage-Text mit PlaceholderAPI-Unterstützung. Namen sind standardmäßig aufrecht; füge <italic> hinzu, wenn du Kursivschrift möchtest. Ein leerer displayName behält den Namen des Gegenstands, statt ihn durch einen leeren zu ersetzen.
x, ySpalte 0 bis 8 und Reihe ab 0 oben.
rollPerSlotFür einen auf mehrere Slots wiederholten Gegenstand mit zufälligem item: aus (Standard) würfelt einmal, und jeder Slot zeigt dieses Ergebnis; an würfelt jeder Slot beim Öffnen des Menüs für sich. Das Ergebnis bleibt, solange das Menü geöffnet ist, außer liveItem ist an.
liveItemAus (Standard): Der Gegenstand wird beim Öffnen des Menüs gezogen und für die ganze Sitzung behalten; beim Aktualisieren folgen nur Name und Beschreibung. An: Der Gegenstand wird bei jeder Aktualisierung neu ausgewertet, ein zufälliger Gegenstand wird also jedes Mal neu gezogen. Mit rollPerSlot an würfelt jeder wiederholte Slot bei jeder Aktualisierung für sich; ohne teilen sich alle wiederholten Slots eine Ziehung pro Aktualisierung. Ein leerer Name wird weiterhin ignoriert.
count, direction, gap, repeatYSlot-Wiederholung, siehe unten.
criteriaDer Slot wird für Spieler, die nicht passen, nicht gezeichnet.
viewPermissionBerechtigung, die zum Sehen des Slots nötig ist.
clickPermissionBerechtigung, die zum Benutzen des Slots nötig ist; ohne sie wird der Slot gezeichnet, ist aber wirkungslos.
allowPickup, isGhostOb das Item aus dem Menü genommen werden kann. Beide sind standardmäßig aus; Ghost-Items können angeklickt, aber nie verschoben oder kopiert werden.
cooldownTicksTicks, bevor derselbe Slot erneut angeklickt werden kann.
interactionList, triggers, modifiersWas ein Klick bewirkt.
inputÖffnet beim Klick einen Texteingabe-Dialog.
storageIdMacht den Slot zu einem persistenten Speicher-Slot aus storagePool.
buttonType, buttonPrefixMarkiert den Slot als Button, der von einer anderen Erweiterung bereitgestellt wird.
animationBewegt den Slot beim Öffnen des Menüs über eine Dauer in Millisekunden an eine Zielposition.

Slot-Wiederholung. count wiederholt ein Item entlang direction (right, left, down, up). gap ist eine Schrittweite, kein Abstand: 1 bedeutet benachbart, 2 lässt einen leeren Slot zwischen den Kopien, und 0 verhält sich wie 1. repeatY wiederholt die ganze Zeile auf der senkrechten Achse. Ohne direction werden count, gap und repeatY ignoriert und es wird ein einzelner Slot platziert. Diese Felder zählen Slots, nie die Stapelgröße des Items.

Überlappungen. Teilen sich zwei Slots eine Zelle, gewinnt der, der etwas bewirkt (eine Klick-Aktion, ein Tag, ein Speicher-Slot), gegenüber einem rein dekorativen, unabhängig von der Reihenfolge. Bei zwei gleichartigen gewinnt der zuletzt deklarierte. Eine Warnung mit der Zelle wird einmal protokolliert.

Klick-Aktionen​

interactionList ordnet einem Klicktyp Befehle und Trigger zu. Die verfügbaren Typen sind LEFT_CLICK, RIGHT_CLICK, SHIFT_LEFT_CLICK, SHIFT_RIGHT_CLICK, MIDDLE_CLICK, DOUBLE_CLICK, NUMBER_KEY_1 bis NUMBER_KEY_9, DROP, DROP_ALL und SWAP_OFFHAND.

  • commands werden von der Konsole ausgeführt. %player% wird durch den Spielernamen ersetzt, und PlaceholderAPI-Platzhalter werden zuerst aufgelöst.
  • triggers lösen TypeWriter-Entries für den Spieler aus. Die eigenen triggers und modifiers des Slots werden bei jedem Links- oder Rechtsklick ausgelöst oder immer dann, wenn eine bestimmte Interaction passt.
  • closeMenu schließt das Fenster nach der Action. executeReturn geht zum vorherigen Menü zurück.

Befehle, die mit gui: beginnen, werden von GUI selbst verarbeitet:

BefehlWirkung
gui:closeSchließt das Menü.
gui:backÖffnet das vorherige Menü der Session erneut.
gui:open <entry_id> oder gui:action <entry_id>Löst einen anderen Entry aus, meist ein weiteres Open GUI.
gui:view <view_id>Wechselt zu einer anderen View, ohne das Inventar zu schließen.
gui:page <delta> [layout_id]Bewegt ein paginiertes oder Leaderboard-Layout um so viele Seiten.
gui:scroll <dx> <dy> [layout_id]Scrollt ein scrollable-Layout.
gui:refreshZeichnet das Menü sofort neu.
gui:sound <sound_key>Spielt dem Spieler einen Sound vor.

Öffnen, Zurück und Schließen​

Ein Open GUI, das aus einem anderen Menü geöffnet wird, wird auf den Session-Verlauf gelegt, sodass gui:back oder executeReturn dorthin zurückführt. Das Schließen mit Escape beendet die Session. Das Öffnen eines Buch-Layouts beendet zuerst die aktuelle Session.

Setze audio, um beim Öffnen, Schließen, Scrollen und Klicken Sounds abzuspielen. Setze autoRefreshTicks, um das Menü bei geöffnetem Zustand alle N Ticks neu zu zeichnen; dadurch ticken Platzhalter in Namen und Lore wie ein Zähler oder Timer.

Views, Tabs und Vererbung​

views machen aus einem open_gui mehrere Bildschirme, die dieselbe Hülle teilen. Ein frame, dessen layoutId @view ist, wird mit dem Layout der aktiven View gefüllt: zuerst über die explizite frames-Zuordnung der View, dann über das Layout mit dem Namen <view id>_<frame id>, dann über dieselben Suchen entlang der parentId der View. Markiere ein Tab-Item mit buttonPrefix view: und buttonType gleich der View-ID, dann wechselt es beim Klick die View und leuchtet auf, solange sie aktiv ist. Der View-Titel akzeptiert {breadcrumb}, {view} und {root}.

baseMenuId verweist auf ein anderes Open GUI und führt dessen layoutPool, views und storagePool unter deinen zusammen: Ein Layout mit derselben id ersetzt das geerbte. Details unter Views, Tabs und Vererbung.

Speicher-Slots​

Ein GUI Storage-Artifact hält die Items, pro Spieler oder pro Gruppe. Deklariere wiederverwendbare Konfigurationen im storagePool des Entrys und gib dann einem Item eine storageId oder verwende ein storage-Layout. Item-Namen und Lore eines Speicher-Slots akzeptieren {stored_name}, {stored_amount} und {stored_max}. {score_raw} und {value_<key>} gibt es außerdem für die Zeilen einer Bestenliste mit source.

Standard-Klickbelegungen, die du in den GUI Global Settings ändern kannst:

AktionStandard-Klick
Ein Item vom Cursor ablegenLinksklick
Den ganzen Cursor-Stapel ablegenShift + Linksklick
Ein Item entnehmenRechtsklick
Alles entnehmenLinksklick
Einen Stapel entnehmenShift + Rechtsklick
Aus dem Inventar füllenZweithand tauschen (F)
Alles auf den Boden fallen lassenWegwerfen (Q)

dropOnClose lässt das, was noch gespeichert ist, den Spieler vor die Füße fallen, wenn das Menü wirklich geschlossen wird, mit Escape oder beim Trennen der Verbindung, aber nicht, wenn der Spieler in ein anderes Menü wechselt.

Erweitertes Inventar​

extendToPlayerInventory zeigt die 36 eigenen Slots des Spielers als vier zusätzliche Reihen an, für eine Zeichenfläche mit zehn Reihen (y 0 bis 9). Das geschieht nur clientseitig: Das echte Inventar wird nie verändert und beim Schließen des Menüs wiederhergestellt, und aus den unteren Reihen können keine Items aufgenommen werden. Es erfordert guiType CUSTOM mit size SIZE_54. Ein Wurzel-Layout, dessen id auf _extended endet, aktiviert es von selbst.

Konfiguration​

GUI hat keine Konfigurationsdatei. Zwei optionale Manifest-Entries passen es an:

  • GUI Extension Configuration aktiviert das debug-Logging und die Option hideVanillaItemStats, standardmäßig an, die Angriffsschaden-, Haltbarkeits- und Verzauberungszeilen auf Menü-Buttons ausblendet.
  • GUI Global Settings legt die Klickbelegungen des Speichers und die Connector-Items des Skilltrees fest.

Platzhalter​

PlatzhalterLiefert
%typewriter_gui_storage_amount_<entry_id>_<slot_index>%Anzahl der für den Spieler in einem GUI Storage-Entry gespeicherten Items, 0 wenn leer.
%typewriter_gui_storage_has_<entry_id>_<slot_index>%true, wenn der Slot ein Item enthält, sonst false.

<slot_index> ist y * 9 + x des Speicher-Slots. Diese Platzhalter lesen immer den eigenen Speicher des Spielers, nie einen gemeinsamen Gruppenspeicher.

In Menüs werden die folgenden Token von der Erweiterung ersetzt: {stored_name}, {stored_amount}, {stored_max} (Speicher-Slots), {page}, {next_page}, {prev_page}, {total_pages} und {page_indicator} (der INDICATOR-Button eines paginierten Layouts) sowie {rank}, {name}, {score}, {group}, {world} und {score_<fact_id>} (Leaderboard-Zeilen).

Entries​

6 Einträge, aus dem Quellcode der Erweiterung generiert.

Aktionen1
Artefakte2
Manifeste3

Fehlerbehebung​

Das Menü öffnet sich leer. mainLayoutId ist leer oder passt zu keiner Layout-id im layoutPool (IDs unterscheiden Groß- und Kleinschreibung). Bei Verwendung von baseMenuId greift eine leere mainLayoutId auf die des Elternteils zurück. Die Startprüfung meldet ein nicht aufgelöstes Hauptlayout in der Konsole.

Ein Slot fehlt und die Konsole meldet „falls outside the grid“. Das Item landete bei einem negativen x oder y oder hinter Spalte 8. Meist liegt das an einem zu großen count, der Slots zählt. Das Log nennt das Layout und die abgelehnten Koordinaten.

Die Konsole meldet „Slot overlap ... gap“. Zwei Slots teilen sich eine Zelle. gap ist eine Schrittweite: 1 platziert benachbarte Slots und 2 lässt jeweils einen leeren Slot dazwischen; wer gap: 1 als „eine Lücke“ liest, erhält Kopien, die auf den Nachbarn der jeweils anderen liegen. Ändere gap oder verschiebe einen Slot.

Ein Slot ist für Admins sichtbar, aber nicht für Spieler. viewPermission nennt eine Berechtigung, die außer Operatoren niemand hat. Leere Werte werden ignoriert, aber ein Tippfehler ist ein echter, nur für Operatoren geltender Node. Dieselbe Regel gilt für die viewPermission einer View.

Ein Button wird angezeigt, tut aber nichts. Prüfe clickPermission, dann cooldownTicks, dann criteria. Hat der Slot einen buttonType, muss sein buttonPrefix zur bereitstellenden Erweiterung passen; ein nicht beanspruchtes Tag behält deine eigene interactionList, aber sonst nichts. Befehle werden von der Konsole ausgeführt, ein Befehl, der einen Spieler als Absender braucht, schlägt daher stillschweigend fehl.

Der scrollbare Inhalt bewegt sich nicht. Prüfe, ob der Inhalt größer als das Fenster ist (virtualWidth und virtualHeight): Ein Pfeil erscheint nur, solange es in seiner Richtung etwas zu scrollen gibt. Ist showDefaultButtons aus und gibt es keine buttons, gibt es überhaupt keinen Pfeil. Ein Standardpfeil weicht außerdem aus, wenn seine Zelle bereits ein Inhalts-Item, einen Button oder eine Dekoration enthält: Es wird nichts protokolliert, verschiebe ihn also mit scrollArrows in GUI Settings oder füge eigene buttons mit einer direction und einem step außerhalb des gescrollten Bereichs hinzu.

Das Leaderboard listet nur Online-Spieler auf. Verknüpfe ein GUI Leaderboard Population-Artifact im Feld population des Leaderboards, um die zuletzt bekannten Werte von Offline-Spielern zu behalten.

Das erweiterte Menü zeigt keine zehn Reihen. extendToPlayerInventory erfordert guiType CUSTOM und size SIZE_54.

Verwandte Erweiterungen​

  • Shops — Shop-Menüs, aufgebaut auf GUI-Layouts und dem Marker shop_button:.
  • Quest Codex — das Quest-Log-Menü, aufgebaut auf demselben open_gui-Chassis.