diff --git a/src/main/kotlin/club/mcscrims/speedhg/gui/anvil/AnvilSearchMenu.kt b/src/main/kotlin/club/mcscrims/speedhg/gui/anvil/AnvilSearchMenu.kt
index c71667a..b1e7956 100644
--- a/src/main/kotlin/club/mcscrims/speedhg/gui/anvil/AnvilSearchMenu.kt
+++ b/src/main/kotlin/club/mcscrims/speedhg/gui/anvil/AnvilSearchMenu.kt
@@ -12,107 +12,53 @@ import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.view.AnvilView
-/**
- * Suchmenü auf Basis der **Paper Anvil-API** (kein NMS!).
- *
- * ## Wie Paper's Anvil-API funktioniert
- *
- * Paper stellt `player.openAnvil(location, force)` bereit. Diese Methode
- * gibt eine `InventoryView` zurück. Da wir uns nicht für die physische Position
- * interessieren (nur das Inventar-UI), übergeben wir `null` als Ort und
- * `true` als Force-Flag (öffnet auch ohne physischen Amboss in der Nähe).
- *
- * ```
- * Slot 0 (INPUT_LEFT) → Das "Such-Icon" mit dem Placeholder-Text
- * Slot 1 (INPUT_RIGHT) → Leer (wird vom Spieler nicht benutzt)
- * Slot 2 (OUTPUT) → Das Ergebnis-Item → Klick bestätigt die Suche
- * ```
- *
- * Der Spieler schreibt in das Umbenennen-Feld des Amboss. Wir lesen den
- * eingegebenen Text über `AnvilView.renameText` aus. Paper aktualisiert
- * diesen Wert in Echtzeit. Beim Klick auf Slot 2 (Output) schließen wir
- * den Amboss und übergeben den Text an [KitSelectorMenu.applySearch].
- *
- * **Warum kein `PrepareAnvilEvent` + Fake-Item?**
- * Für unsere reine Text-Eingabe brauchen wir kein Live-Feedback im Output-Slot.
- * Wir setzen ein statisches Bestätigungs-Item und lesen den Rename-Text beim
- * Klick aus. Das ist einfacher und stabiler.
- *
- * @param player Der suchende Spieler.
- * @param returnMenu Das [KitSelectorMenu] zu dem wir nach der Suche zurückspringen.
- * @param initialText Vorausgefüllter Text (wird als Rename-Text gesetzt).
- */
@Suppress("DEPRECATION")
class AnvilSearchMenu(
private val player: Player,
private val returnMenu: KitSelectorMenu,
private val initialText: String = ""
) {
- private val plugin = SpeedHG.instance
+ private val plugin get() = SpeedHG.instance
+ private val lm get() = plugin.languageManager
private val mm = MiniMessage.miniMessage()
- /** Öffnet das Anvil-Inventar. */
fun open(player: Player) {
- // Paper API: öffnet einen Amboss ohne physischen Block
- val view = player.openAnvil(null, true) ?: return
+ val view = player.openAnvil(null, true) ?: return
val anvilInv = view.topInventory as? AnvilInventory ?: return
- // ── Slot 0: Such-Icon (Input) ──────────────────────────────────────
anvilInv.setItem(0, buildInputItem())
-
- // ── Slot 2: Bestätigungs-Icon (Output) ────────────────────────────
anvilInv.setItem(2, buildConfirmItem())
-
- // Kosten auf 0 setzen — Spieler soll kein XP zahlen
anvilInv.repairCost = 0
- // Klick-Listener merken uns über die AnvilTracker-Map
AnvilSearchTracker.register(player, this)
}
- /**
- * Verarbeitet einen Klick im Anvil-Inventory.
- * Wird vom [MenuListener] über [AnvilSearchTracker] weitergeleitet.
- *
- * @param event Das Click-Event (bereits gecancelt).
- * @param view Die geöffnete [AnvilView] mit dem Eingabetext.
- */
fun onClick(event: InventoryClickEvent, view: AnvilView) {
event.isCancelled = true
-
- // Nur Klick auf Output-Slot (Slot 2) bestätigt die Suche
if (event.rawSlot != 2) return
val query = view.renameText ?: ""
-
- // Amboss schließen und zurück zum Kit-Menü
player.closeInventory()
AnvilSearchTracker.unregister(player)
-
- // Suchbegriff anwenden → öffnet KitSelectorMenu neu
returnMenu.applySearch(query)
}
- /** Cleanup wenn Spieler Amboss schließt ohne zu bestätigen. */
fun onClose() {
AnvilSearchTracker.unregister(player)
- // Zurück zum Kit-Menü ohne Suchbegriff zu ändern
- // Einen Tick warten, damit das aktuelle Close-Event fertig ist
plugin.server.scheduler.runTask(plugin) { ->
returnMenu.open(player)
}
}
- // -------------------------------------------------------------------------
- // Item-Builder
- // -------------------------------------------------------------------------
+ // ── Item-Builder ──────────────────────────────────────────────────────────
private fun buildInputItem(): ItemStack {
+ val rawPlaceholder = initialText.ifEmpty { lm.getRawMessage(player, "gui.anvil_search.input_placeholder") }
+
val item = ItemStack(Material.NAME_TAG)
item.editMeta { meta ->
meta.displayName(
- // Der Name des Input-Items wird als Placeholder-Text im Umbenennungsfeld angezeigt
- mm.deserialize(initialText.ifEmpty { "Suchbegriff eingeben..." })
+ mm.deserialize(rawPlaceholder)
.decoration(TextDecoration.ITALIC, false)
)
}
@@ -123,31 +69,24 @@ class AnvilSearchMenu(
val item = ItemStack(Material.NAME_TAG)
item.editMeta { meta ->
meta.displayName(
- mm.deserialize("✔ Suche bestätigen")
+ mm.deserialize(lm.getRawMessage(player, "gui.anvil_search.confirm_name"))
.decoration(TextDecoration.ITALIC, false)
)
- val lore = listOf(
+ meta.lore(listOf(
Component.empty(),
- mm.deserialize("Klicken um zu suchen")
+ mm.deserialize(lm.getRawMessage(player, "gui.anvil_search.confirm_click"))
.decoration(TextDecoration.ITALIC, false),
Component.empty()
- )
- meta.lore(lore)
+ ))
}
return item
}
}
-/**
- * Hält die Zuordnung `Player → AnvilSearchMenu` für alle aktuell offenen
- * Anvil-Suchen. Wird benötigt, weil Anvil-Inventories keinen eigenen
- * [MenuHolder] haben — sie werden direkt von Bukkit verwaltet.
- *
- * Die Map wird im [MenuListener] abgefragt.
- */
object AnvilSearchTracker {
- private val openSearches = java.util.concurrent.ConcurrentHashMap()
+ private val openSearches =
+ java.util.concurrent.ConcurrentHashMap()
fun register(player: Player, menu: AnvilSearchMenu) {
openSearches[player.uniqueId] = menu
diff --git a/src/main/kotlin/club/mcscrims/speedhg/gui/factory/KitItemFactory.kt b/src/main/kotlin/club/mcscrims/speedhg/gui/factory/KitItemFactory.kt
index 954d198..bb23200 100644
--- a/src/main/kotlin/club/mcscrims/speedhg/gui/factory/KitItemFactory.kt
+++ b/src/main/kotlin/club/mcscrims/speedhg/gui/factory/KitItemFactory.kt
@@ -1,94 +1,69 @@
package club.mcscrims.speedhg.gui.factory
+import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.kit.Kit
import club.mcscrims.speedhg.kit.Playstyle
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.format.TextDecoration
import net.kyori.adventure.text.minimessage.MiniMessage
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
+import org.bukkit.Material
import org.bukkit.enchantments.Enchantment
+import org.bukkit.entity.Player
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
-/**
- * Erstellt dynamisch die [ItemStack]s für das Kit-Auswahl-Menü.
- *
- * ## Warum eine eigene Factory?
- *
- * Die Item-Generierung (Icon, Name, Lore, Enchants) ist von [KitSelectorMenu]
- * trennbar und testbar. Außerdem kann sie wiederverwendet werden (z.B. für
- * Hotbar-Items oder Chat-Vorschauen).
- *
- * ## Lore-Aufbau
- * ```
- * ─────────────────────────
- *
- *
- *
- * Playstyle: ► Aggressive
- *
- * [L-Klick] Kit auswählen
- * [R-Klick] Playstyle wechseln
- * ─────────────────────────
- * ```
- */
object KitItemFactory {
+ private val plugin get() = SpeedHG.instance
private val mm = MiniMessage.miniMessage()
- /**
- * Baut das vollständige Kit-Item inklusive dynamischer Lore.
- *
- * @param kit Das Kit, das dargestellt werden soll.
- * @param currentStyle Der aktuell gewählte [Playstyle] des Spielers.
- * @param isSelected Ob dieses Kit gerade das aktiv gewählte ist.
- */
+ // ── Kit-Item ──────────────────────────────────────────────────────────────
+
fun buildKitItem(
kit: Kit,
currentStyle: Playstyle,
- isSelected: Boolean
+ isSelected: Boolean,
+ player: Player
): ItemStack {
+ val lm = plugin.languageManager
val item = ItemStack(kit.icon)
item.editMeta { meta ->
- // ── Name ──────────────────────────────────────────────────────────
meta.displayName(
- kit.displayName
- .decoration(TextDecoration.ITALIC, false)
+ kit.displayName.decoration(TextDecoration.ITALIC, false)
)
- // ── Lore ──────────────────────────────────────────────────────────
val lore = mutableListOf()
- // Trennlinie
lore += separator()
- // Kit-eigene Lore-Zeilen
kit.lore.forEach { line ->
- lore += mm.deserialize(line)
- .decoration(TextDecoration.ITALIC, false)
+ lore += mm.deserialize(line).decoration(TextDecoration.ITALIC, false)
}
lore += Component.empty()
- // Playstyle-Anzeige
lore += mm.deserialize(
- "Playstyle: ► ${currentStyle.displayName}"
+ lm.getRawMessage(player, "gui.kit_selector.kit_item.playstyle"),
+ Placeholder.parsed("playstyle", currentStyle.displayName)
).decoration(TextDecoration.ITALIC, false)
lore += Component.empty()
- // Interaktions-Hints
- lore += mm.deserialize("[L-Click] Select Kit")
- .decoration(TextDecoration.ITALIC, false)
- lore += mm.deserialize("[R-Click] Change playstyle")
- .decoration(TextDecoration.ITALIC, false)
+ lore += mm.deserialize(
+ lm.getRawMessage(player, "gui.kit_selector.kit_item.left_click")
+ ).decoration(TextDecoration.ITALIC, false)
+
+ lore += mm.deserialize(
+ lm.getRawMessage(player, "gui.kit_selector.kit_item.right_click")
+ ).decoration(TextDecoration.ITALIC, false)
lore += separator()
meta.lore(lore)
- // ── Ausgewählt-Effekt ──────────────────────────────────────────────
if (isSelected) {
meta.addEnchant(Enchantment.UNBREAKING, 1, true)
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS)
@@ -103,66 +78,77 @@ object KitItemFactory {
return item
}
- // ── Dekorations-Items ─────────────────────────────────────────────────────
+ // ── Dekorations- und Navigations-Items ───────────────────────────────────
fun buildFillerItem(): ItemStack {
- val item = ItemStack(org.bukkit.Material.GRAY_STAINED_GLASS_PANE)
+ val item = ItemStack(Material.GRAY_STAINED_GLASS_PANE)
item.editMeta { meta ->
- meta.displayName(Component.text(" ").decoration(TextDecoration.ITALIC, false))
+ meta.displayName(
+ Component.text(" ").decoration(TextDecoration.ITALIC, false)
+ )
}
return item
}
- fun buildPrevPageItem(): ItemStack = buildNavItem(
- org.bukkit.Material.ARROW,
- "◄ Previous"
+ fun buildPrevPageItem(player: Player): ItemStack = buildNavItem(
+ Material.ARROW,
+ plugin.languageManager.getRawMessage(player, "gui.kit_selector.prev_page")
)
- fun buildNextPageItem(): ItemStack = buildNavItem(
- org.bukkit.Material.ARROW,
- "Next ►"
+ fun buildNextPageItem(player: Player): ItemStack = buildNavItem(
+ Material.ARROW,
+ plugin.languageManager.getRawMessage(player, "gui.kit_selector.next_page")
)
- fun buildSearchItem(currentQuery: String): ItemStack {
- val item = ItemStack(org.bukkit.Material.NAME_TAG)
+ fun buildSearchItem(currentQuery: String, player: Player): ItemStack {
+ val lm = plugin.languageManager
+ val item = ItemStack(Material.NAME_TAG)
+
item.editMeta { meta ->
meta.displayName(
- mm.deserialize("🔍 Search")
+ mm.deserialize(lm.getRawMessage(player, "gui.kit_selector.search.name"))
.decoration(TextDecoration.ITALIC, false)
)
+
val lore = mutableListOf()
lore += separator()
+
if (currentQuery.isNotEmpty()) {
- lore += mm.deserialize("Current: \"$currentQuery\"")
- .decoration(TextDecoration.ITALIC, false)
+ lore += mm.deserialize(
+ lm.getRawMessage(player, "gui.kit_selector.search.current"),
+ Placeholder.parsed("query", currentQuery)
+ ).decoration(TextDecoration.ITALIC, false)
lore += Component.empty()
}
- lore += mm.deserialize("Click to search")
- .decoration(TextDecoration.ITALIC, false)
+
+ lore += mm.deserialize(
+ lm.getRawMessage(player, "gui.kit_selector.search.click")
+ ).decoration(TextDecoration.ITALIC, false)
+
lore += separator()
meta.lore(lore)
}
+
return item
}
- fun buildClearSearchItem(): ItemStack = buildNavItem(
- org.bukkit.Material.BARRIER,
- "✕ Reset search"
+ fun buildClearSearchItem(player: Player): ItemStack = buildNavItem(
+ Material.BARRIER,
+ plugin.languageManager.getRawMessage(player, "gui.kit_selector.clear_search")
)
- fun buildCloseItem(): ItemStack = buildNavItem(
- org.bukkit.Material.DARK_OAK_DOOR,
- "✕ Close"
+ fun buildCloseItem(player: Player): ItemStack = buildNavItem(
+ Material.DARK_OAK_DOOR,
+ plugin.languageManager.getRawMessage(player, "gui.kit_selector.close")
)
// ── Interne Hilfsmittel ───────────────────────────────────────────────────
- private fun buildNavItem(material: org.bukkit.Material, title: String): ItemStack {
+ private fun buildNavItem(material: Material, rawTitle: String): ItemStack {
val item = ItemStack(material)
item.editMeta { meta ->
meta.displayName(
- mm.deserialize(title)
- .decoration(TextDecoration.ITALIC, false)
+ mm.deserialize(rawTitle).decoration(TextDecoration.ITALIC, false)
)
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ADDITIONAL_TOOLTIP)
}
diff --git a/src/main/kotlin/club/mcscrims/speedhg/gui/menu/KitSelectorMenu.kt b/src/main/kotlin/club/mcscrims/speedhg/gui/menu/KitSelectorMenu.kt
index a998438..f97dd00 100644
--- a/src/main/kotlin/club/mcscrims/speedhg/gui/menu/KitSelectorMenu.kt
+++ b/src/main/kotlin/club/mcscrims/speedhg/gui/menu/KitSelectorMenu.kt
@@ -5,7 +5,7 @@ import club.mcscrims.speedhg.gui.anvil.AnvilSearchMenu
import club.mcscrims.speedhg.gui.factory.KitItemFactory
import club.mcscrims.speedhg.kit.Kit
import club.mcscrims.speedhg.kit.Playstyle
-import net.kyori.adventure.text.minimessage.MiniMessage
+import club.mcscrims.speedhg.util.trans
import org.bukkit.entity.Player
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent
@@ -32,23 +32,19 @@ import org.bukkit.inventory.Inventory
class KitSelectorMenu(
private val player: Player,
private var searchQuery: String = ""
-) : Menu(rows = 6, title = "Kit-Auswahl") {
+) : Menu(
+ rows = 6,
+ title = player.trans( "gui.kit_selector.title" )
+) {
- private val plugin = SpeedHG.instance
- private val mm = MiniMessage.miniMessage()
+ private val plugin get() = SpeedHG.instance
+ private val lm get() = plugin.languageManager
// Pagination
private val kitSlots = 45 // Slots 0–44 für Kits
private var currentPage = 0
// ── Slot-Konstanten ────────────────────────────────────────────────────────
- private val slotPrevPage = 45
- private val slotSearch = 48
- private val slotClearSearch = 50
- private val slotClose = 53
- private val slotNextPage = 53 // wird durch slotClose ersetzt wenn letzte Seite
-
- // ── Navigation-Slots ──────────────────────────────────────────────────────
private val navSlotPrev = 45
private val navSlotSearch = 48
private val navSlotClear = 50
@@ -59,7 +55,7 @@ class KitSelectorMenu(
// -------------------------------------------------------------------------
override fun build(): Inventory {
- val inv = createInventory(mm.deserialize(title))
+ val inv = createInventory(title) // title ist jetzt bereits ein Component
populate(inv)
return inv
}
@@ -67,70 +63,65 @@ class KitSelectorMenu(
private fun populate(inv: Inventory) {
inv.clear()
- // ── Filler ────────────────────────────────────────────────────────────
+ // Filler-Reihe
val filler = KitItemFactory.buildFillerItem()
(45 until 54).forEach { inv.setItem(it, filler) }
- // ── Kits ──────────────────────────────────────────────────────────────
+ // Kits
val filteredKits = getFilteredKits()
- val totalPages = ((filteredKits.size - 1) / kitSlots + 1).coerceAtLeast(1)
+ val totalPages = ((filteredKits.size - 1) / kitSlots + 1).coerceAtLeast(1)
- // Seiten-Clamp: wenn Suche Kits reduziert, nicht auf nicht-existenter Seite bleiben
currentPage = currentPage.coerceIn(0, totalPages - 1)
val pageStart = currentPage * kitSlots
- val pageKits = filteredKits.subList(
+ val pageKits = filteredKits.subList(
pageStart.coerceAtMost(filteredKits.size),
(pageStart + kitSlots).coerceAtMost(filteredKits.size)
)
pageKits.forEachIndexed { slotIndex, kit ->
val currentStyle = plugin.kitManager.getSelectedPlaystyle(player)
- val selectedKit = plugin.kitManager.getSelectedKit(player)
- inv.setItem(slotIndex, KitItemFactory.buildKitItem(kit, currentStyle, selectedKit?.id == kit.id))
+ val selectedKit = plugin.kitManager.getSelectedKit(player)
+ inv.setItem(
+ slotIndex,
+ KitItemFactory.buildKitItem(kit, currentStyle, selectedKit?.id == kit.id, player)
+ )
}
- // ── Navigation ────────────────────────────────────────────────────────
+ // Navigation
if (currentPage > 0)
- inv.setItem(navSlotPrev, KitItemFactory.buildPrevPageItem())
+ inv.setItem(navSlotPrev, KitItemFactory.buildPrevPageItem(player))
if (currentPage < totalPages - 1)
- inv.setItem(navSlotNext, KitItemFactory.buildNextPageItem())
+ inv.setItem(navSlotNext, KitItemFactory.buildNextPageItem(player))
- inv.setItem(navSlotSearch, KitItemFactory.buildSearchItem(searchQuery))
+ inv.setItem(navSlotSearch, KitItemFactory.buildSearchItem(searchQuery, player))
if (searchQuery.isNotEmpty())
- inv.setItem(navSlotClear, KitItemFactory.buildClearSearchItem())
+ inv.setItem(navSlotClear, KitItemFactory.buildClearSearchItem(player))
}
- // -------------------------------------------------------------------------
- // Klick-Handling
- // -------------------------------------------------------------------------
+ // ── Klick-Handling ────────────────────────────────────────────────────────
override fun onClick(event: InventoryClickEvent, player: Player) {
val slot = event.rawSlot
if (slot !in 0.. handlePrevPage()
- navSlotNext -> handleNextPage()
- navSlotSearch -> handleSearchClick()
- navSlotClear -> handleClearSearch()
- in 0 until kitSlots -> handleKitClick(slot, event.click)
+ navSlotPrev -> handlePrevPage()
+ navSlotNext -> handleNextPage()
+ navSlotSearch -> handleSearchClick()
+ navSlotClear -> handleClearSearch()
+ in 0 until kitSlots -> handleKitClick(slot, event.click)
}
}
- // -------------------------------------------------------------------------
- // Kit-Interaktionen
- // -------------------------------------------------------------------------
+ // ── Kit-Interaktionen ─────────────────────────────────────────────────────
private fun handleKitClick(slot: Int, clickType: ClickType) {
val kit = getKitAtSlot(slot) ?: return
-
when {
- // Linksklick → Kit auswählen
clickType.isLeftClick -> selectKit(kit)
- // Rechtsklick → Playstyle toggeln (und Menü refreshen)
clickType.isRightClick -> togglePlaystyle(kit)
}
}
@@ -138,27 +129,27 @@ class KitSelectorMenu(
private fun selectKit(kit: Kit) {
plugin.kitManager.selectKit(player, kit)
player.sendActionBar(
- MiniMessage.miniMessage().deserialize(
- "Kit ${kit.displayName} gewählt!"
+ lm.getComponent(
+ player, "gui.kit_selector.kit_selected",
+ mapOf(), mapOf("kit" to kit.displayName)
)
)
- // Menü aktualisieren um Auswahl-Glanz zu zeigen
refresh()
}
private fun togglePlaystyle(kit: Kit) {
val current = plugin.kitManager.getSelectedPlaystyle(player)
- val next = when (current) {
+ val next = when (current) {
Playstyle.AGGRESSIVE -> Playstyle.DEFENSIVE
Playstyle.DEFENSIVE -> Playstyle.AGGRESSIVE
}
plugin.kitManager.selectPlaystyle(player, next)
- // Wenn dieses Kit gerade ausgewählt ist, Playstyle-Änderung übernehmen
if (plugin.kitManager.getSelectedKit(player)?.id == kit.id) {
player.sendActionBar(
- MiniMessage.miniMessage().deserialize(
- "Playstyle: ► ${next.displayName}"
+ lm.getComponent(
+ player, "gui.kit_selector.playstyle_changed",
+ mapOf("playstyle" to next.displayName)
)
)
}
@@ -166,32 +157,20 @@ class KitSelectorMenu(
refresh()
}
- // -------------------------------------------------------------------------
- // Navigation
- // -------------------------------------------------------------------------
+ // ── Navigation ────────────────────────────────────────────────────────────
private fun handlePrevPage() {
- if (currentPage > 0) {
- currentPage--
- refresh()
- }
+ if (currentPage > 0) { currentPage--; refresh() }
}
private fun handleNextPage() {
val totalPages = ((getFilteredKits().size - 1) / kitSlots + 1).coerceAtLeast(1)
- if (currentPage < totalPages - 1) {
- currentPage++
- refresh()
- }
+ if (currentPage < totalPages - 1) { currentPage++; refresh() }
}
private fun handleSearchClick() {
- // Öffne das Anvil-Suchmenü; schließt dieses Menü temporär
- AnvilSearchMenu(
- player = player,
- returnMenu = this,
- initialText = searchQuery
- ).open(player)
+ AnvilSearchMenu(player = player, returnMenu = this, initialText = searchQuery)
+ .open(player)
}
private fun handleClearSearch() {
@@ -200,23 +179,14 @@ class KitSelectorMenu(
refresh()
}
- // -------------------------------------------------------------------------
- // Hilfsmittel
- // -------------------------------------------------------------------------
+ // ── Hilfsmittel ───────────────────────────────────────────────────────────
- /** Aktualisiert das geöffnete Inventory in-place ohne es neu zu öffnen. */
- fun refresh() {
- populate(inventory)
- }
+ fun refresh() { populate(inventory) }
- /**
- * Aktualisiert den Suchbegriff und baut das Menü neu auf.
- * Wird vom [AnvilSearchMenu] aufgerufen nachdem der Spieler einen Begriff eingegeben hat.
- */
fun applySearch(query: String) {
searchQuery = query.trim()
currentPage = 0
- open(player) // neu öffnen (Anvil hat das vorherige Inventory geschlossen)
+ open(player)
}
private fun getFilteredKits(): List {
@@ -225,19 +195,14 @@ class KitSelectorMenu(
val q = searchQuery.lowercase()
return allKits.filter { kit ->
- // Suche im Plain-Text des Adventure-Components
kit.id.lowercase().contains(q) ||
net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
- .plainText()
- .serialize(kit.displayName)
- .lowercase()
- .contains(q)
+ .plainText().serialize(kit.displayName).lowercase().contains(q)
}
}
private fun getKitAtSlot(slot: Int): Kit? {
- val filteredKits = getFilteredKits()
val absoluteIndex = currentPage * kitSlots + slot
- return filteredKits.getOrNull(absoluteIndex)
+ return getFilteredKits().getOrNull(absoluteIndex)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/club/mcscrims/speedhg/gui/menu/Menu.kt b/src/main/kotlin/club/mcscrims/speedhg/gui/menu/Menu.kt
index 1504fc7..ef94cf9 100644
--- a/src/main/kotlin/club/mcscrims/speedhg/gui/menu/Menu.kt
+++ b/src/main/kotlin/club/mcscrims/speedhg/gui/menu/Menu.kt
@@ -1,5 +1,6 @@
package club.mcscrims.speedhg.gui.menu
+import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
@@ -25,7 +26,7 @@ import org.bukkit.inventory.Inventory
*/
abstract class Menu(
protected val rows: Int,
- protected val title: String
+ protected val title: Component
) {
protected val size: Int = rows * 9
internal lateinit var inventory: Inventory
@@ -56,7 +57,7 @@ abstract class Menu(
* Erstellt ein Inventory mit dem korrekten [MenuHolder].
* Immer statt `Bukkit.createInventory(null, ...)` verwenden.
*/
- protected fun createInventory(parsedTitle: net.kyori.adventure.text.Component): Inventory {
+ protected fun createInventory(parsedTitle: Component): Inventory {
val holder = MenuHolder(this)
val inv = Bukkit.createInventory(holder, size, parsedTitle)
holder.bind(inv)
diff --git a/src/main/resources/languages/en_US.yml b/src/main/resources/languages/en_US.yml
index 7616e86..77d7ee3 100644
--- a/src/main/resources/languages/en_US.yml
+++ b/src/main/resources/languages/en_US.yml
@@ -95,6 +95,28 @@ scoreboard:
- ""
- "play.mcscrims.club"
+gui:
+ kit_selector:
+ title: 'Kit Selection'
+ kit_selected: 'Kit selected!'
+ playstyle_changed: 'Playstyle: ► '
+ prev_page: '◄ Previous'
+ next_page: 'Next ►'
+ clear_search: '✕ Reset Search'
+ close: '✕ Close'
+ kit_item:
+ playstyle: 'Playstyle: ► '
+ left_click: '[L-Click] Select Kit'
+ right_click: '[R-Click] Change Playstyle'
+ search:
+ name: '🔍 Search'
+ current: 'Current: ""'
+ click: 'Click to search'
+ anvil_search:
+ input_placeholder: 'Enter search term...'
+ confirm_name: '✔ Confirm Search'
+ confirm_click: 'Click to confirm'
+
kits:
backup:
name: 'Backup'