mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
book edit kind of working
This commit is contained in:
parent
2a1cade9f1
commit
1b39707500
3 changed files with 180 additions and 82 deletions
|
|
@ -15,15 +15,18 @@ import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
import org.bukkit.inventory.AnvilInventory
|
import org.bukkit.inventory.AnvilInventory
|
||||||
import org.bukkit.inventory.InventoryView
|
import org.bukkit.inventory.InventoryView
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.BookMeta
|
||||||
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
import xyz.alexcrea.cuanvil.dependency.DependencyManager
|
||||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
|
||||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
|
||||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
||||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
||||||
|
import xyz.alexcrea.cuanvil.util.AnvilLoreEditUtil
|
||||||
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
||||||
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
|
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
|
||||||
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
|
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
|
||||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||||
|
import java.util.*
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class AnvilResultListener : Listener {
|
class AnvilResultListener : Listener {
|
||||||
|
|
@ -65,40 +68,53 @@ class AnvilResultListener: Listener {
|
||||||
event.result = Event.Result.ALLOW
|
event.result = Event.Result.ALLOW
|
||||||
onCustomCraft(
|
onCustomCraft(
|
||||||
event, recipe, player,
|
event, recipe, player,
|
||||||
leftItem, rightItem, output, inventory)
|
leftItem, rightItem, output, inventory
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val canMerge = leftItem.canMergeWith(rightItem)
|
// Do not continue if there was no change
|
||||||
val unitRepairResult = leftItem.getRepair(rightItem)
|
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))) {
|
||||||
val allowed = (rightItem == null)
|
|
||||||
|| (canMerge)
|
|
||||||
|| (unitRepairResult != null)
|
|
||||||
|
|
||||||
// True if there was no change or not allowed
|
|
||||||
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))
|
|
||||||
|| !allowed
|
|
||||||
) {
|
|
||||||
event.result = Event.Result.DENY
|
event.result = Event.Result.DENY
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rename
|
||||||
if (rightItem == null) {
|
if (rightItem == null) {
|
||||||
event.result = Event.Result.ALLOW
|
event.result = Event.Result.ALLOW
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Merge
|
||||||
|
val canMerge = leftItem.canMergeWith(rightItem)
|
||||||
if (canMerge) {
|
if (canMerge) {
|
||||||
event.result = Event.Result.ALLOW
|
event.result = Event.Result.ALLOW
|
||||||
} else if (unitRepairResult != null) {
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unit repair
|
||||||
|
val unitRepairResult = leftItem.getRepair(rightItem)
|
||||||
|
if (unitRepairResult != null) {
|
||||||
onUnitRepairExtract(
|
onUnitRepairExtract(
|
||||||
leftItem, rightItem, output,
|
leftItem, rightItem, output,
|
||||||
unitRepairResult, event, player, inventory
|
unitRepairResult, event, player, inventory
|
||||||
)
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For lore edit
|
||||||
|
if (handleBookLoreEdit(event, inventory, player, leftItem, rightItem, output)) {
|
||||||
|
return
|
||||||
|
} else if (Material.PAPER == rightItem.type) {
|
||||||
|
//TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onCustomCraft(event: InventoryClickEvent,
|
// Else there was no working situation somehow so we deny
|
||||||
|
event.result = Event.Result.DENY
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onCustomCraft(
|
||||||
|
event: InventoryClickEvent,
|
||||||
recipe: AnvilCustomRecipe,
|
recipe: AnvilCustomRecipe,
|
||||||
player: Player,
|
player: Player,
|
||||||
leftItem: ItemStack,
|
leftItem: ItemStack,
|
||||||
|
|
@ -123,7 +139,8 @@ class AnvilResultListener: Listener {
|
||||||
|
|
||||||
// Handle not creative middle click...
|
// Handle not creative middle click...
|
||||||
if (event.click != ClickType.MIDDLE &&
|
if (event.click != ClickType.MIDDLE &&
|
||||||
!handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost)) return
|
!handleCustomCraftClick(event, recipe, inventory, player, leftItem, rightItem, amount, xpCost)
|
||||||
|
) return
|
||||||
|
|
||||||
// Finally, we add the item to the player
|
// Finally, we add the item to the player
|
||||||
if (slotDestination.type == SlotType.CURSOR) {
|
if (slotDestination.type == SlotType.CURSOR) {
|
||||||
|
|
@ -133,10 +150,12 @@ class AnvilResultListener: Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleCustomCraftClick(event: InventoryClickEvent, recipe: AnvilCustomRecipe,
|
private fun handleCustomCraftClick(
|
||||||
|
event: InventoryClickEvent, recipe: AnvilCustomRecipe,
|
||||||
inventory: AnvilInventory, player: Player,
|
inventory: AnvilInventory, player: Player,
|
||||||
leftItem: ItemStack, rightItem: ItemStack?,
|
leftItem: ItemStack, rightItem: ItemStack?,
|
||||||
amount: Int, xpCost: Int): Boolean {
|
amount: Int, xpCost: Int
|
||||||
|
): Boolean {
|
||||||
// We remove what should be removed
|
// We remove what should be removed
|
||||||
if (rightItem != null) {
|
if (rightItem != null) {
|
||||||
if (recipe.rightItem == null) return false// in case it changed
|
if (recipe.rightItem == null) return false// in case it changed
|
||||||
|
|
@ -174,6 +193,48 @@ class AnvilResultListener: Listener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun extractAnvilResult(
|
||||||
|
event: InventoryClickEvent,
|
||||||
|
player: Player,
|
||||||
|
inventory: AnvilInventory,
|
||||||
|
leftItem: ItemStack,
|
||||||
|
leftRemoveCount: Int,
|
||||||
|
rightItem: ItemStack,
|
||||||
|
rightRemoveCount: Int,
|
||||||
|
output: ItemStack,
|
||||||
|
repairCost: Int,
|
||||||
|
): Boolean {
|
||||||
|
// Assumed if player do not have enough xp then it returned MIN_VALUE
|
||||||
|
if (repairCost == Int.MIN_VALUE) return false
|
||||||
|
|
||||||
|
// Where should we get the item
|
||||||
|
val slotDestination = getActionSlot(event, player)
|
||||||
|
if (slotDestination.type == SlotType.NO_SLOT) return false
|
||||||
|
|
||||||
|
// If not creative middle click...
|
||||||
|
if (event.click != ClickType.MIDDLE) {
|
||||||
|
// We remove what should be removed
|
||||||
|
leftItem.amount -= leftRemoveCount
|
||||||
|
inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
|
||||||
|
|
||||||
|
rightItem.amount -= rightRemoveCount
|
||||||
|
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
|
||||||
|
|
||||||
|
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||||
|
player.level -= repairCost
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, we add the item to the player
|
||||||
|
if (SlotType.CURSOR == slotDestination.type) {
|
||||||
|
player.setItemOnCursor(output)
|
||||||
|
} else {// We assume SlotType == SlotType.INVENTORY
|
||||||
|
player.inventory.setItem(slotDestination.slot, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO probably anvil damage & sound here ??
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun onUnitRepairExtract(
|
private fun onUnitRepairExtract(
|
||||||
leftItem: ItemStack,
|
leftItem: ItemStack,
|
||||||
rightItem: ItemStack,
|
rightItem: ItemStack,
|
||||||
|
|
@ -191,36 +252,24 @@ class AnvilResultListener: Listener {
|
||||||
// To avoid vanilla, we cancel the event for unit repair
|
// To avoid vanilla, we cancel the event for unit repair
|
||||||
event.result = Event.Result.DENY
|
event.result = Event.Result.DENY
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
// And we give the item manually
|
|
||||||
// But first we check if we should give the item
|
|
||||||
val slotDestination = getActionSlot(event, player)
|
|
||||||
if (slotDestination.type == SlotType.NO_SLOT) return
|
|
||||||
|
|
||||||
// Test repair cost
|
// Get repair cost
|
||||||
val repairCost = getUnitRepairCost(inventory, player, leftItem, output, resultCopy, resultAmount)
|
val repairCost = getUnitRepairCost(inventory, player, leftItem, output, resultCopy, resultAmount)
|
||||||
if(repairCost == Int.MIN_VALUE) return
|
|
||||||
|
|
||||||
// If not creative middle click...
|
// And then we give the item manually
|
||||||
if (event.click != ClickType.MIDDLE) {
|
extractAnvilResult(
|
||||||
// We remove what should be removed
|
event, player, inventory,
|
||||||
inventory.setItem(ANVIL_INPUT_LEFT, null)
|
leftItem, 1,
|
||||||
rightItem.amount -= resultAmount
|
rightItem, resultAmount,
|
||||||
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
|
output, repairCost
|
||||||
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
)
|
||||||
player.level -= repairCost
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we add the item to the player
|
private fun getUnitRepairCost(
|
||||||
if (slotDestination.type == SlotType.CURSOR) {
|
inventory: AnvilInventory, player: Player,
|
||||||
player.setItemOnCursor(output)
|
|
||||||
} else {// We assume SlotType == SlotType.INVENTORY
|
|
||||||
player.inventory.setItem(slotDestination.slot, output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getUnitRepairCost(inventory: AnvilInventory, player: Player,
|
|
||||||
leftItem: ItemStack, output: ItemStack,
|
leftItem: ItemStack, output: ItemStack,
|
||||||
resultCopy: ItemStack, resultAmount: Int): Int {
|
resultCopy: ItemStack, resultAmount: Int
|
||||||
|
): Int {
|
||||||
if (player.gameMode == GameMode.CREATIVE) return 0
|
if (player.gameMode == GameMode.CREATIVE) return 0
|
||||||
|
|
||||||
var repairCost = 0
|
var repairCost = 0
|
||||||
|
|
@ -257,6 +306,51 @@ class AnvilResultListener: Listener {
|
||||||
return repairCost
|
return repairCost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleBookLoreEdit(
|
||||||
|
event: InventoryClickEvent,
|
||||||
|
inventory: AnvilInventory,
|
||||||
|
player: Player,
|
||||||
|
leftItem: ItemStack,
|
||||||
|
rightItem: ItemStack,
|
||||||
|
output: ItemStack,
|
||||||
|
): Boolean {
|
||||||
|
if (Material.WRITABLE_BOOK != rightItem.type) return false
|
||||||
|
val bookMeta = rightItem.itemMeta as BookMeta
|
||||||
|
|
||||||
|
val editType = AnvilLoreEditUtil.bookLoreEditTypeAppend(leftItem, rightItem) ?: return false
|
||||||
|
|
||||||
|
if (editType) {
|
||||||
|
if (output != AnvilLoreEditUtil.handleLoreAppendByBook(player, leftItem, bookMeta)) return false
|
||||||
|
|
||||||
|
// Remove pages to
|
||||||
|
val bookCopy = rightItem.clone()
|
||||||
|
bookMeta.pages = Collections.emptyList()
|
||||||
|
bookCopy.itemMeta = bookMeta
|
||||||
|
|
||||||
|
return extractAnvilResult(
|
||||||
|
event, player, inventory,
|
||||||
|
leftItem, 1,
|
||||||
|
bookCopy, 0,
|
||||||
|
output, 0
|
||||||
|
) //TODO DO REPAIR COST
|
||||||
|
} else {
|
||||||
|
if (output != AnvilLoreEditUtil.handleLoreRemoveByBook(player, leftItem, rightItem, bookMeta)) return false
|
||||||
|
|
||||||
|
// remove lore
|
||||||
|
val leftCopy = leftItem.clone()
|
||||||
|
val leftMeta = leftCopy.itemMeta
|
||||||
|
leftMeta!!.lore = null
|
||||||
|
leftCopy.itemMeta = leftMeta
|
||||||
|
|
||||||
|
return extractAnvilResult(
|
||||||
|
event, player, inventory,
|
||||||
|
leftCopy, 0,
|
||||||
|
rightItem, 1,
|
||||||
|
output, 0
|
||||||
|
) //TODO DO REPAIR COST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the destination slot or "NO_SLOT" slot container if there is no slot available
|
* Get the destination slot or "NO_SLOT" slot container if there is no slot available
|
||||||
*/
|
*/
|
||||||
|
|
@ -283,8 +377,7 @@ class AnvilResultListener: Listener {
|
||||||
return NO_SLOT
|
return NO_SLOT
|
||||||
}
|
}
|
||||||
return SlotContainer(SlotType.INVENTORY, slotIndex)
|
return SlotContainer(SlotType.INVENTORY, slotIndex)
|
||||||
}
|
} else if (player.itemOnCursor.type != Material.AIR) return NO_SLOT
|
||||||
else if (player.itemOnCursor.type != Material.AIR) return NO_SLOT
|
|
||||||
return CURSOR_SLOT
|
return CURSOR_SLOT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ class PrepareAnvilListener : Listener {
|
||||||
event.result = result
|
event.result = result
|
||||||
|
|
||||||
// TODO forgot about xp config & logic
|
// TODO forgot about xp config & logic
|
||||||
// AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, 1)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,19 @@ object AnvilLoreEditUtil {
|
||||||
return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER)
|
return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? {
|
fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? {
|
||||||
if (!hasLoreEditByBookPermission(player)) return null
|
if (!hasLoreEditByBookPermission(player)) return null
|
||||||
|
|
||||||
val result = first.clone()
|
val result = first.clone()
|
||||||
val meta = result.itemMeta
|
val meta = result.itemMeta
|
||||||
|
//TODO take into account previous lore
|
||||||
meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled
|
meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled
|
||||||
result.itemMeta = meta
|
result.itemMeta = meta
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? {
|
fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? {
|
||||||
if (!hasLoreEditByBookPermission(player)) return null
|
if (!hasLoreEditByBookPermission(player)) return null
|
||||||
|
|
||||||
val meta = first.itemMeta
|
val meta = first.itemMeta
|
||||||
|
|
@ -52,7 +53,8 @@ object AnvilLoreEditUtil {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bookLoreEditType(second: ItemStack) : Boolean? {
|
// Return true if append, false if remove, null if neither
|
||||||
|
fun bookLoreEditTypeAppend(first: ItemStack, second: ItemStack): Boolean? {
|
||||||
// Test if the book & quil contain content
|
// Test if the book & quil contain content
|
||||||
val meta = second.itemMeta as BookMeta
|
val meta = second.itemMeta as BookMeta
|
||||||
|
|
||||||
|
|
@ -72,15 +74,18 @@ object AnvilLoreEditUtil {
|
||||||
if (meta.pages[0].isEmpty()) return null
|
if (meta.pages[0].isEmpty()) return null
|
||||||
if (ConfigOptions.appendLoreBookAndQuil)
|
if (ConfigOptions.appendLoreBookAndQuil)
|
||||||
return true
|
return true
|
||||||
}
|
} else if (ConfigOptions.removeLoreBookAndQuil) {
|
||||||
else if(ConfigOptions.removeLoreBookAndQuil) {
|
if (!first.hasItemMeta()) return null
|
||||||
return false
|
|
||||||
|
val leftMeta = first.itemMeta!!
|
||||||
|
return if (leftMeta.hasLore()) false
|
||||||
|
else null
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? {
|
fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack): ItemStack? {
|
||||||
val bookType = bookLoreEditType(second) ?: return null
|
val bookType = bookLoreEditTypeAppend(first, second) ?: return null
|
||||||
|
|
||||||
val meta = second.itemMeta as BookMeta
|
val meta = second.itemMeta as BookMeta
|
||||||
return if (bookType) handleLoreAppendByBook(player, first, meta)
|
return if (bookType) handleLoreAppendByBook(player, first, meta)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue