1.2.0
Изменения: - ТЕПЕРЬ ЗАЛАМИНИРОВАННЫЕ КАРТЫ НЕЛЬЗЯ ДЮПАТЬ В КРАФТЕРЕ (ОТКЛЮЧАЕМ ВАНИЛЬНЫЕ МЕХАНИКИ, ОУУ Е) - Теперь можно подписывать предметы при помощи бирки в наковальне и окрашивать это название путём совмещения предмета с биркой и красителем в наковальне.
This commit is contained in:
parent
1789f5907e
commit
e0789c4a9d
3 changed files with 690 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package dev.marrow.zsign
|
||||
|
||||
import com.github.shynixn.mccoroutine.bukkit.SuspendingJavaPlugin
|
||||
import dev.marrow.zsign.listeners.AnvilUseListener
|
||||
import dev.marrow.zsign.listeners.MapLaminationListener
|
||||
import dev.marrow.zsign.utils.CommonUtils.gson
|
||||
import dev.marrow.zsign.utils.ComponentExtension.deserializeMiniMessage
|
||||
|
|
@ -24,6 +25,7 @@ class Core : SuspendingJavaPlugin() {
|
|||
|
||||
// Только наш cartography-слушатель
|
||||
server.pluginManager.registerEvents(MapLaminationListener(this), this)
|
||||
server.pluginManager.registerEvents(AnvilUseListener(this), this)
|
||||
|
||||
this.lifecycleManager.registerEventHandler(LifecycleEvents.COMMANDS) {
|
||||
}
|
||||
|
|
|
|||
202
src/main/kotlin/dev/marrow/zsign/listeners/AnvilUseListener.kt
Normal file
202
src/main/kotlin/dev/marrow/zsign/listeners/AnvilUseListener.kt
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
package dev.marrow.zsign.listeners
|
||||
|
||||
import dev.marrow.zsign.Core
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.format.NamedTextColor
|
||||
import net.kyori.adventure.text.format.TextColor
|
||||
import net.kyori.adventure.text.format.TextDecoration
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.ClickType
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.event.inventory.InventoryType
|
||||
import org.bukkit.event.inventory.PrepareAnvilEvent
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.Repairable
|
||||
|
||||
class AnvilUseListener(private val plugin: Core) : Listener {
|
||||
|
||||
private val config get() = plugin.config
|
||||
private val banSymbols get() = config.getStringList("ban-symbols")
|
||||
private val streamerWords get() = config.getStringList("streamer-words")
|
||||
|
||||
companion object {
|
||||
private const val SECOND_SLOT = 1
|
||||
private val colorMap = mapOf(
|
||||
Material.RED_DYE to TextColor.color(0xE6060C),
|
||||
Material.BROWN_DYE to TextColor.color(0xAA5500),
|
||||
Material.ORANGE_DYE to TextColor.color(0xFFAA00),
|
||||
Material.YELLOW_DYE to TextColor.color(0xFFEE4C),
|
||||
Material.LIME_DYE to TextColor.color(0x55FF55),
|
||||
Material.GREEN_DYE to TextColor.color(0x00AA00),
|
||||
Material.LIGHT_BLUE_DYE to TextColor.color(0x55FFFF),
|
||||
Material.CYAN_DYE to TextColor.color(0x00AAAA),
|
||||
Material.BLUE_DYE to TextColor.color(0x4842EA),
|
||||
Material.PURPLE_DYE to TextColor.color(0xAA00AA),
|
||||
Material.MAGENTA_DYE to TextColor.color(0xDC89BF),
|
||||
Material.PINK_DYE to TextColor.color(0xFFB6C1),
|
||||
Material.WHITE_DYE to TextColor.color(0xFFFFFF),
|
||||
Material.LIGHT_GRAY_DYE to TextColor.color(0xAAAAAA),
|
||||
Material.GRAY_DYE to TextColor.color(0x555555),
|
||||
Material.BLACK_DYE to TextColor.color(0x000000)
|
||||
)
|
||||
private val plain = PlainTextComponentSerializer.plainText()
|
||||
private fun ItemStack?.isAir(): Boolean = this == null || type == Material.AIR
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
fun onPrepareAnvil(e: PrepareAnvilEvent) {
|
||||
val inv = e.inventory
|
||||
val firstItem = inv.firstItem ?: return
|
||||
val secondItem = inv.secondItem
|
||||
val renameText = inv.renameText?.takeIf { it.isNotBlank() }
|
||||
|
||||
if (secondItem != null && (secondItem.type == Material.NAME_TAG || secondItem.type in colorMap.keys) && secondItem.amount > 1) {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
|
||||
var newName: String? = null
|
||||
if (renameText != null) {
|
||||
var censored = renameText
|
||||
streamerWords.forEach { word ->
|
||||
censored = censored?.replace(word, "*".repeat(word.length), ignoreCase = true)
|
||||
}
|
||||
banSymbols.forEach { symbol ->
|
||||
if (censored?.contains(symbol) ?: false) {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
}
|
||||
newName = censored
|
||||
}
|
||||
|
||||
val isCustom = secondItem != null && (secondItem.type == Material.NAME_TAG || secondItem.type in colorMap.keys)
|
||||
var result: ItemStack? = e.result
|
||||
if (result == null && !isCustom && newName == null) return
|
||||
if (result == null) result = firstItem.clone()
|
||||
|
||||
val meta = result.itemMeta ?: run {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
|
||||
if (newName != null) {
|
||||
meta.displayName(Component.text(newName))
|
||||
}
|
||||
|
||||
if (secondItem != null) {
|
||||
val lore = meta.lore()?.toMutableList() ?: mutableListOf()
|
||||
val hashtagIndex = lore.indexOfFirst { plain.serialize(it).startsWith("#") }
|
||||
val hasHashtag = hashtagIndex != -1
|
||||
|
||||
if (secondItem.type == Material.NAME_TAG) {
|
||||
if (hasHashtag) {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
val playerName = e.viewers.firstOrNull()?.name ?: "player"
|
||||
lore.add(Component.empty())
|
||||
lore.add(Component.text("#$playerName", NamedTextColor.GRAY).decoration(TextDecoration.ITALIC, false))
|
||||
meta.lore(lore)
|
||||
(meta as? Repairable)?.repairCost = 1
|
||||
inv.repairCost = 1
|
||||
} else if (secondItem.type in colorMap.keys) {
|
||||
if (!hasHashtag) {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
val currentHashtagText = plain.serialize(lore[hashtagIndex])
|
||||
val playerName = currentHashtagText.removePrefix("#")
|
||||
val color = colorMap.getValue(secondItem.type)
|
||||
lore[hashtagIndex] = Component.text("#$playerName", color).decoration(TextDecoration.ITALIC, false)
|
||||
meta.lore(lore)
|
||||
(meta as? Repairable)?.repairCost = 1
|
||||
inv.repairCost = 1
|
||||
}
|
||||
}
|
||||
|
||||
result.itemMeta = meta
|
||||
|
||||
if (result.isSimilar(firstItem)) {
|
||||
e.result = null
|
||||
return
|
||||
}
|
||||
|
||||
e.result = result
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
fun onAnvilInsert(e: InventoryClickEvent) {
|
||||
val inv = e.inventory
|
||||
if (inv.type != InventoryType.ANVIL) return
|
||||
val p = e.whoClicked as? Player ?: return
|
||||
|
||||
val firstItem = inv.first()
|
||||
if (firstItem.isAir()) return
|
||||
|
||||
val cursor = p.itemOnCursor
|
||||
|
||||
if (e.clickedInventory === inv && e.rawSlot == SECOND_SLOT && (cursor.type == Material.NAME_TAG || cursor.type in colorMap.keys)) {
|
||||
e.isCancelled = true
|
||||
val placeAmount = if (e.click == ClickType.RIGHT) 1 else cursor.amount
|
||||
val toPlace = placeAmount.coerceAtMost(1)
|
||||
if (toPlace > 0) {
|
||||
val current = inv.getItem(SECOND_SLOT)
|
||||
val newItem = cursor.clone()
|
||||
newItem.amount = 1
|
||||
inv.setItem(SECOND_SLOT, newItem)
|
||||
cursor.amount -= 1
|
||||
p.setItemOnCursor(if (cursor.amount > 0) cursor else ItemStack(Material.AIR))
|
||||
if (current != null && !current.isAir()) {
|
||||
p.inventory.addItem(current.clone().apply { amount = 1 })
|
||||
}
|
||||
p.scheduler.runDelayed(plugin, { _ -> p.updateInventory() }, null, 1L)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (e.clickedInventory === inv && e.rawSlot == SECOND_SLOT && e.click == ClickType.NUMBER_KEY) {
|
||||
val idx = e.hotbarButton
|
||||
if (idx in 0..8) {
|
||||
val hot = p.inventory.getItem(idx)
|
||||
if ((hot?.type == Material.NAME_TAG || hot?.type in colorMap.keys) && (hot?.amount ?: 0) > 0) {
|
||||
e.isCancelled = true
|
||||
val current = inv.getItem(SECOND_SLOT)
|
||||
val newItem = hot!!.clone()
|
||||
newItem.amount = 1
|
||||
inv.setItem(SECOND_SLOT, newItem)
|
||||
hot.amount -= 1
|
||||
p.inventory.setItem(idx, if (hot.amount > 0) hot else ItemStack(Material.AIR))
|
||||
if (current != null && !current.isAir()) {
|
||||
p.inventory.addItem(current.clone().apply { amount = 1 })
|
||||
}
|
||||
p.scheduler.runDelayed(plugin, { _ -> p.updateInventory() }, null, 1L)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (e.clickedInventory !== inv && e.isShiftClick) {
|
||||
val clicked = e.currentItem ?: return
|
||||
if (clicked.type == Material.NAME_TAG || clicked.type in colorMap.keys) {
|
||||
e.isCancelled = true
|
||||
val current = inv.getItem(SECOND_SLOT)
|
||||
val newItem = clicked.clone()
|
||||
newItem.amount = 1
|
||||
inv.setItem(SECOND_SLOT, newItem)
|
||||
clicked.amount -= 1
|
||||
e.clickedInventory?.setItem(e.slot, if (clicked.amount > 0) clicked else ItemStack(Material.AIR))
|
||||
if (current != null && !current.isAir()) {
|
||||
p.inventory.addItem(current.clone().apply { amount = 1 })
|
||||
}
|
||||
p.scheduler.runDelayed(plugin, { _ -> p.updateInventory() }, null, 1L)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue