mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 08:14:00 +02:00
hell
This commit is contained in:
parent
171a8cad6d
commit
7aac325c70
6 changed files with 130 additions and 56 deletions
|
|
@ -18,4 +18,6 @@ interface AnvilRenameDialog {
|
||||||
|
|
||||||
fun currentText(player: HumanEntity): String?
|
fun currentText(player: HumanEntity): String?
|
||||||
|
|
||||||
|
fun isOpenFor(player: HumanEntity): Boolean
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -32,7 +32,7 @@ class AnvilRenameDialogImpl(
|
||||||
val keepUserPreviousDialog: Supplier<Boolean>,
|
val keepUserPreviousDialog: Supplier<Boolean>,
|
||||||
val maxLength: Supplier<Int>,
|
val maxLength: Supplier<Int>,
|
||||||
val plugin: Plugin,
|
val plugin: Plugin,
|
||||||
): AnvilRenameDialog {
|
) : AnvilRenameDialog {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val RENAME_TEXT_KEY = "rename"
|
private const val RENAME_TEXT_KEY = "rename"
|
||||||
|
|
@ -43,16 +43,24 @@ class AnvilRenameDialogImpl(
|
||||||
|
|
||||||
// Need to be able to translate it later !
|
// Need to be able to translate it later !
|
||||||
private val USER_FACING_RENAME_TITLE = Component.text("Rename Your Item")
|
private val USER_FACING_RENAME_TITLE = Component.text("Rename Your Item")
|
||||||
private val USER_FACING_WARNING = Component.text("Note that the repair text will appear blank after Confirm\n" +
|
private val USER_FACING_WARNING = Component.text(
|
||||||
"But the name will be correctly applied")
|
"Note that the repair text will appear blank after Confirm\n" +
|
||||||
|
"But the name will be correctly applied"
|
||||||
|
)
|
||||||
private val USER_FACING_CONFIRM = Component.text("Confirm").color(TextColor.fromHexString("#40FF40"))
|
private val USER_FACING_CONFIRM = Component.text("Confirm").color(TextColor.fromHexString("#40FF40"))
|
||||||
private val USER_FACING_CANCEL = Component.text("Cancel").color(TextColor.fromHexString("#FF4040"))
|
private val USER_FACING_CANCEL = Component.text("Cancel").color(TextColor.fromHexString("#FF4040"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private val lastNames = HashMap<UUID, String>()
|
private val lastNames = HashMap<UUID, String>()
|
||||||
|
private val lastRenames = HashMap<UUID, String>()
|
||||||
|
|
||||||
|
|
||||||
private val lastLeftItem = HashMap<UUID, String>()
|
private val lastLeftItem = HashMap<UUID, String>()
|
||||||
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||||
|
|
||||||
|
// For monetary cost
|
||||||
|
val hasUiOpen = HashSet<UUID>()
|
||||||
|
|
||||||
private val containerField = CraftInventoryView::class.java.getDeclaredField("container")
|
private val containerField = CraftInventoryView::class.java.getDeclaredField("container")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
@ -63,14 +71,15 @@ class AnvilRenameDialogImpl(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun makeDialog(initial: String?, callback: Consumer<String?>): Dialog {
|
fun makeDialog(playerID: UUID, initial: String?, callback: Consumer<String?>): Dialog {
|
||||||
val maxLength = this.maxLength.get()
|
val maxLength = this.maxLength.get()
|
||||||
val initialFinal = initial?.take(maxLength)
|
val initialFinal = initial?.take(maxLength)
|
||||||
|
|
||||||
val baseBuilder = DialogBase.builder(USER_FACING_RENAME_TITLE)
|
val baseBuilder = DialogBase.builder(USER_FACING_RENAME_TITLE)
|
||||||
.canCloseWithEscape(true)
|
.canCloseWithEscape(false)
|
||||||
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
.afterAction(DialogBase.DialogAfterAction.CLOSE)
|
||||||
.inputs(listOf(
|
.inputs(
|
||||||
|
listOf(
|
||||||
DialogInput.text(RENAME_TEXT_KEY, Component.text("Rename text"))
|
DialogInput.text(RENAME_TEXT_KEY, Component.text("Rename text"))
|
||||||
.maxLength(maxLength)
|
.maxLength(maxLength)
|
||||||
.initial(initialFinal ?: "")
|
.initial(initialFinal ?: "")
|
||||||
|
|
@ -79,59 +88,73 @@ class AnvilRenameDialogImpl(
|
||||||
.build(),
|
.build(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
baseBuilder.body(listOf(
|
baseBuilder.body(
|
||||||
|
listOf(
|
||||||
DialogBody.plainMessage(USER_FACING_WARNING, MAX_WIDTH)
|
DialogBody.plainMessage(USER_FACING_WARNING, MAX_WIDTH)
|
||||||
))
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return Dialog.create { builder -> builder.empty()
|
return Dialog.create { builder ->
|
||||||
|
builder.empty()
|
||||||
.base(baseBuilder.build())
|
.base(baseBuilder.build())
|
||||||
.type(DialogType.confirmation(
|
.type(
|
||||||
|
DialogType.confirmation(
|
||||||
ActionButton.builder(USER_FACING_CONFIRM)
|
ActionButton.builder(USER_FACING_CONFIRM)
|
||||||
.action(DialogAction.customClick({ response, _ ->
|
.action(DialogAction.customClick({ response, _ ->
|
||||||
|
hasUiOpen.remove(playerID)
|
||||||
val text = response.getText(RENAME_TEXT_KEY)!!
|
val text = response.getText(RENAME_TEXT_KEY)!!
|
||||||
callback.accept(text)
|
callback.accept(text)
|
||||||
}, ClickCallback.Options.builder().build()))
|
}, ClickCallback.Options.builder().build()))
|
||||||
.build(),
|
.build(),
|
||||||
ActionButton.builder(USER_FACING_CANCEL)
|
ActionButton.builder(USER_FACING_CANCEL)
|
||||||
|
.action(DialogAction.customClick({ response, _ ->
|
||||||
|
hasUiOpen.remove(playerID)
|
||||||
|
}, ClickCallback.Options.builder().build()))
|
||||||
.build(),
|
.build(),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setResult(player: HumanEntity, view: CraftAnvilView, result: String?) {
|
private fun setResult(player: HumanEntity, view: CraftAnvilView, result: String?) {
|
||||||
val defaultName = PLAIN_TEXT_SERIALIZER.serializeOrNull(view.getItem(0)?.effectiveName())
|
val defaultName = PLAIN_TEXT_SERIALIZER.serializeOrNull(view.getItem(0)?.effectiveName())
|
||||||
if(defaultName == result) {
|
if (defaultName == result) {
|
||||||
setName(player, view, "")
|
setName(player, view, "", null)
|
||||||
if(defaultName != null) lastNames[player.uniqueId] = defaultName
|
if (defaultName != null) lastNames[player.uniqueId] = defaultName
|
||||||
}
|
} else setName(player, view, lastNames[player.uniqueId], result)
|
||||||
else setName(player, view, result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setName(player: HumanEntity, view: CraftAnvilView, name: String?) {
|
private fun setName(player: HumanEntity, view: CraftAnvilView, name: String?, rename: String?) {
|
||||||
val menu = (containerField.get(view) as AnvilMenu)
|
val menu = (containerField.get(view) as AnvilMenu)
|
||||||
val isSameName = menu.itemName == name
|
val isSameName = menu.itemName == name
|
||||||
menu.itemName = name
|
menu.itemName = name
|
||||||
|
|
||||||
if(name == null)
|
if (name == null)
|
||||||
lastNames.remove(player.uniqueId)
|
lastNames.remove(player.uniqueId)
|
||||||
else
|
else
|
||||||
lastNames[player.uniqueId] = name
|
lastNames[player.uniqueId] = name
|
||||||
|
|
||||||
if(!isSameName)
|
if (rename == null)
|
||||||
|
lastRenames.remove(player.uniqueId)
|
||||||
|
else
|
||||||
|
lastRenames[player.uniqueId] = rename
|
||||||
|
|
||||||
|
if (!isSameName)
|
||||||
CraftEventFactory.callPrepareResultEvent(menu, 2);
|
CraftEventFactory.callPrepareResultEvent(menu, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun nameFromItem(player: HumanEntity, item: ItemStack?): String? {
|
private fun nameFromItem(player: HumanEntity, item: ItemStack?): String? {
|
||||||
// Already has text
|
// Already has text
|
||||||
if(item?.hasItemMeta() != true || !item.itemMeta.hasCustomName())
|
if (item?.hasItemMeta() != true || !item.itemMeta.hasCustomName())
|
||||||
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
return PLAIN_TEXT_SERIALIZER.serializeOrNull(item?.effectiveName())
|
||||||
|
|
||||||
if(keepUserPreviousDialog.get() && item.hasItemMeta()) {
|
if (keepUserPreviousDialog.get() && item.hasItemMeta()) {
|
||||||
val lastName = item.itemMeta.persistentDataContainer.get(
|
val lastName = item.itemMeta.persistentDataContainer.get(
|
||||||
AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY,
|
AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY,
|
||||||
PersistentDataType.STRING)
|
PersistentDataType.STRING
|
||||||
|
)
|
||||||
|
|
||||||
if(lastName != null) return lastName
|
if (lastName != null) return lastName
|
||||||
}
|
}
|
||||||
|
|
||||||
return fromFormated.apply(player, item.effectiveName())
|
return fromFormated.apply(player, item.effectiveName())
|
||||||
|
|
@ -139,33 +162,37 @@ class AnvilRenameDialogImpl(
|
||||||
|
|
||||||
private fun tryShowDialogScheduled(player: HumanEntity, event: PrepareAnvilEvent) {
|
private fun tryShowDialogScheduled(player: HumanEntity, event: PrepareAnvilEvent) {
|
||||||
val view = event.view
|
val view = event.view
|
||||||
if(view !is CraftAnvilView) return
|
if (view !is CraftAnvilView) return
|
||||||
|
|
||||||
val renameText = view.renameText
|
val renameText = view.renameText
|
||||||
val leftItem = view.getItem(0)
|
val leftItem = view.getItem(0)
|
||||||
val leftItemStr = leftItem?.toString()
|
val leftItemStr = leftItem?.toString()
|
||||||
val lastName = lastNames.getOrDefault(player.uniqueId, null)
|
|
||||||
|
|
||||||
if(lastLeftItem.getOrDefault(player.uniqueId, null) != leftItemStr) {
|
val lastName = lastNames.getOrDefault(player.uniqueId, null)
|
||||||
if(leftItemStr == null)
|
val lastRename = lastRenames.getOrDefault(player.uniqueId, null)
|
||||||
|
|
||||||
|
if (lastLeftItem.getOrDefault(player.uniqueId, null) != leftItemStr) {
|
||||||
|
if (leftItemStr == null)
|
||||||
lastLeftItem.remove(player.uniqueId)
|
lastLeftItem.remove(player.uniqueId)
|
||||||
else lastLeftItem[player.uniqueId] = leftItemStr
|
else lastLeftItem[player.uniqueId] = leftItemStr
|
||||||
|
|
||||||
setName(player, view, nameFromItem(player, leftItem))
|
setName(player, view, renameText, nameFromItem(player, leftItem))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastName == renameText)
|
if (lastName == renameText)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(renameText?.isBlank() == true) {
|
if (renameText?.isBlank() == true) {
|
||||||
setName(player, view, lastNames[player.uniqueId])
|
setName(player, view, lastName, lastRename)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val dialog = makeDialog(lastName)
|
val dialog = makeDialog(player.uniqueId, lastRename)
|
||||||
{ result -> setResult(player, view, result) }
|
{ result -> setResult(player, view, result) }
|
||||||
player.showDialog(dialog)
|
player.showDialog(dialog)
|
||||||
|
|
||||||
|
hasUiOpen.add(player.uniqueId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to wait for a short time as changing item will change the name BEFORE the item change
|
// We need to wait for a short time as changing item will change the name BEFORE the item change
|
||||||
|
|
@ -181,7 +208,7 @@ class AnvilRenameDialogImpl(
|
||||||
{},
|
{},
|
||||||
2
|
2
|
||||||
)
|
)
|
||||||
if(task == null) return
|
if (task == null) return
|
||||||
|
|
||||||
runTaskMap[player.uniqueId] = task
|
runTaskMap[player.uniqueId] = task
|
||||||
}
|
}
|
||||||
|
|
@ -196,4 +223,8 @@ class AnvilRenameDialogImpl(
|
||||||
return lastNames[player.uniqueId]
|
return lastNames[player.uniqueId]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isOpenFor(player: HumanEntity): Boolean {
|
||||||
|
return hasUiOpen.contains(player.uniqueId)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,45 @@
|
||||||
package xyz.alexcrea.cuanvil.util
|
package xyz.alexcrea.cuanvil.util
|
||||||
|
|
||||||
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask
|
||||||
|
import org.bukkit.entity.HumanEntity
|
||||||
import org.bukkit.inventory.InventoryView
|
import org.bukkit.inventory.InventoryView
|
||||||
|
import org.bukkit.plugin.Plugin
|
||||||
|
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
|
||||||
|
import java.util.HashMap
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
// TODO yet another cleanup to do on legacy removal branch
|
|
||||||
object AnvilTitleUtil {
|
object AnvilTitleUtil {
|
||||||
|
|
||||||
fun rename(view: InventoryView, name: String) {
|
private val runTaskMap = HashMap<UUID, ScheduledTask>()
|
||||||
if(view.title == name) return
|
|
||||||
|
private fun actualRename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog) {
|
||||||
|
runTaskMap.remove(player.uniqueId)
|
||||||
|
if (view.title == name) return
|
||||||
|
|
||||||
|
// We assume rename impl is used
|
||||||
|
if (anvilDialog.isOpenFor(player)) return
|
||||||
|
|
||||||
view.title = name
|
view.title = name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't want to rename instantly it is causing issue with rename text
|
||||||
|
// especially as it can "override" current ui when it is rename ui time but rename ui also need some delay
|
||||||
|
fun rename(view: InventoryView, name: String, player: HumanEntity, anvilDialog: AnvilRenameDialog, plugin: Plugin) {
|
||||||
|
runTaskMap.remove(player.uniqueId)?.cancel()
|
||||||
|
|
||||||
|
val task = player.scheduler.runDelayed(
|
||||||
|
plugin,
|
||||||
|
{ _ ->
|
||||||
|
run { actualRename(view, name, player, anvilDialog) }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
runTaskMap.remove(player.uniqueId)
|
||||||
|
},
|
||||||
|
2
|
||||||
|
)
|
||||||
|
|
||||||
|
if (task == null) return
|
||||||
|
runTaskMap[player.uniqueId] = task
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +59,8 @@ class PrepareAnvilListener : Listener {
|
||||||
if(player !is Player) return
|
if(player !is Player) return
|
||||||
val inventory = event.inventory
|
val inventory = event.inventory
|
||||||
|
|
||||||
|
tryRenameDialog(player, event)
|
||||||
|
|
||||||
// Test if custom anvil is bypassed before immutability test
|
// Test if custom anvil is bypassed before immutability test
|
||||||
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) {
|
if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) {
|
||||||
// even if we got bypassed we still want to set price
|
// even if we got bypassed we still want to set price
|
||||||
|
|
@ -87,8 +89,6 @@ class PrepareAnvilListener : Listener {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tryRenameDialog(player, event)
|
|
||||||
|
|
||||||
// Test if the event should bypass custom anvil.
|
// Test if the event should bypass custom anvil.
|
||||||
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
|
if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
|
||||||
// even if we got bypassed we still want to set price
|
// even if we got bypassed we still want to set price
|
||||||
|
|
@ -127,7 +127,7 @@ class PrepareAnvilListener : Listener {
|
||||||
|
|
||||||
private fun setNoResult(event: PrepareAnvilEvent, view: InventoryView) {
|
private fun setNoResult(event: PrepareAnvilEvent, view: InventoryView) {
|
||||||
event.result = null
|
event.result = null
|
||||||
AnvilXpUtil.onNoResult(view)
|
// TODO AnvilXpUtil.onNoResult(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryRenameDialog(
|
private fun tryRenameDialog(
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,10 @@ object AnvilXpUtil {
|
||||||
|
|
||||||
val text = "Cost: " + (if(has) "§2" else "§4") +
|
val text = "Cost: " + (if(has) "§2" else "§4") +
|
||||||
EconomyManager.economy!!.format(finalCost)
|
EconomyManager.economy!!.format(finalCost)
|
||||||
AnvilTitleUtil.rename(view, text)
|
AnvilTitleUtil.rename(view, text,
|
||||||
|
player,
|
||||||
|
AnvilRenameDialogUtil.anvilRenameDialog,
|
||||||
|
CustomAnvil.instance)
|
||||||
|
|
||||||
clearAnvilXpCost(inventory, view, player)
|
clearAnvilXpCost(inventory, view, player)
|
||||||
}
|
}
|
||||||
|
|
@ -229,7 +232,10 @@ object AnvilXpUtil {
|
||||||
|
|
||||||
fun onNoResult(player: HumanEntity, view: InventoryView) {
|
fun onNoResult(player: HumanEntity, view: InventoryView) {
|
||||||
if (ConfigOptions.shouldUseMoney(player))
|
if (ConfigOptions.shouldUseMoney(player))
|
||||||
AnvilTitleUtil.rename(view, "")
|
AnvilTitleUtil.rename(view, "",
|
||||||
|
player,
|
||||||
|
AnvilRenameDialogUtil.anvilRenameDialog,
|
||||||
|
CustomAnvil.instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exclusivePenaltyKey(useType: AnvilUseType): NamespacedKey {
|
private fun exclusivePenaltyKey(useType: AnvilUseType): NamespacedKey {
|
||||||
|
|
|
||||||
|
|
@ -47,5 +47,9 @@ object AnvilRenameDialogUtil {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isOpenFor(player: HumanEntity): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue