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
20f9de084d
commit
b25e3961c2
3 changed files with 180 additions and 82 deletions
|
|
@ -15,18 +15,21 @@ import org.bukkit.event.inventory.InventoryClickEvent
|
|||
import org.bukkit.inventory.AnvilInventory
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.BookMeta
|
||||
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_RIGHT
|
||||
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
|
||||
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
|
||||
import xyz.alexcrea.cuanvil.util.AnvilLoreEditUtil
|
||||
import xyz.alexcrea.cuanvil.util.AnvilUseType
|
||||
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
|
||||
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
|
||||
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
class AnvilResultListener: Listener {
|
||||
class AnvilResultListener : Listener {
|
||||
|
||||
companion object {
|
||||
// static slot container
|
||||
|
|
@ -48,57 +51,70 @@ class AnvilResultListener: Listener {
|
|||
}
|
||||
|
||||
// Test if the event should bypass custom anvil.
|
||||
if(DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
|
||||
if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
|
||||
|
||||
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
|
||||
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
|
||||
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
|
||||
|
||||
if(GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) {
|
||||
if (GameMode.CREATIVE != player.gameMode && inventory.repairCost >= inventory.maximumRepairCost) {
|
||||
event.result = Event.Result.DENY
|
||||
return
|
||||
}
|
||||
|
||||
// Test custom recipe
|
||||
val recipe = CustomRecipeUtil.getCustomRecipe(leftItem, rightItem)
|
||||
if(recipe != null){
|
||||
if (recipe != null) {
|
||||
event.result = Event.Result.ALLOW
|
||||
onCustomCraft(
|
||||
event, recipe, player,
|
||||
leftItem, rightItem, output, inventory)
|
||||
leftItem, rightItem, output, inventory
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
val canMerge = leftItem.canMergeWith(rightItem)
|
||||
val unitRepairResult = leftItem.getRepair(rightItem)
|
||||
val allowed = (rightItem == null)
|
||||
|| (canMerge)
|
||||
|| (unitRepairResult != null)
|
||||
|
||||
// True if there was no change or not allowed
|
||||
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))
|
||||
|| !allowed
|
||||
) {
|
||||
// Do not continue if there was no change
|
||||
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))) {
|
||||
event.result = Event.Result.DENY
|
||||
return
|
||||
}
|
||||
|
||||
// Rename
|
||||
if (rightItem == null) {
|
||||
event.result = Event.Result.ALLOW
|
||||
return
|
||||
}
|
||||
|
||||
// Merge
|
||||
val canMerge = leftItem.canMergeWith(rightItem)
|
||||
if (canMerge) {
|
||||
event.result = Event.Result.ALLOW
|
||||
} else if (unitRepairResult != null) {
|
||||
return
|
||||
}
|
||||
|
||||
// Unit repair
|
||||
val unitRepairResult = leftItem.getRepair(rightItem)
|
||||
if (unitRepairResult != null) {
|
||||
onUnitRepairExtract(
|
||||
leftItem, rightItem, output,
|
||||
unitRepairResult, event, player, inventory
|
||||
)
|
||||
|
||||
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,
|
||||
player: Player,
|
||||
leftItem: ItemStack,
|
||||
|
|
@ -108,7 +124,7 @@ class AnvilResultListener: Listener {
|
|||
) {
|
||||
event.result = Event.Result.DENY
|
||||
|
||||
if(recipe.leftItem == null) return // in case it changed
|
||||
if (recipe.leftItem == null) return // in case it changed
|
||||
|
||||
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, leftItem, rightItem)
|
||||
val xpCost = amount * recipe.xpCostPerCraft
|
||||
|
|
@ -123,7 +139,8 @@ class AnvilResultListener: Listener {
|
|||
|
||||
// Handle not creative middle click...
|
||||
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
|
||||
if (slotDestination.type == SlotType.CURSOR) {
|
||||
|
|
@ -133,13 +150,15 @@ class AnvilResultListener: Listener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleCustomCraftClick(event: InventoryClickEvent, recipe: AnvilCustomRecipe,
|
||||
private fun handleCustomCraftClick(
|
||||
event: InventoryClickEvent, recipe: AnvilCustomRecipe,
|
||||
inventory: AnvilInventory, player: Player,
|
||||
leftItem: ItemStack, rightItem: ItemStack?,
|
||||
amount: Int, xpCost: Int): Boolean {
|
||||
amount: Int, xpCost: Int
|
||||
): Boolean {
|
||||
// We remove what should be removed
|
||||
if(rightItem != null){
|
||||
if(recipe.rightItem == null) return false// in case it changed
|
||||
if (rightItem != null) {
|
||||
if (recipe.rightItem == null) return false// in case it changed
|
||||
|
||||
rightItem.amount -= amount * recipe.rightItem!!.amount
|
||||
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
|
||||
|
|
@ -148,7 +167,7 @@ class AnvilResultListener: Listener {
|
|||
leftItem.amount -= amount * recipe.leftItem!!.amount
|
||||
inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
|
||||
|
||||
if(player.gameMode != GameMode.CREATIVE){
|
||||
if (player.gameMode != GameMode.CREATIVE) {
|
||||
player.level -= xpCost
|
||||
}
|
||||
|
||||
|
|
@ -156,9 +175,9 @@ class AnvilResultListener: Listener {
|
|||
val newAmount = CustomRecipeUtil.getCustomRecipeAmount(recipe, leftItem, rightItem)
|
||||
|
||||
CustomAnvil.verboseLog("new amount is $newAmount")
|
||||
if(newAmount <= 0 || recipe.exactCount){
|
||||
if (newAmount <= 0 || recipe.exactCount) {
|
||||
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
}else{
|
||||
} else {
|
||||
val resultItem: ItemStack = recipe.resultItem!!.clone()
|
||||
resultItem.amount *= newAmount
|
||||
|
||||
|
|
@ -174,6 +193,48 @@ class AnvilResultListener: Listener {
|
|||
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(
|
||||
leftItem: ItemStack,
|
||||
rightItem: ItemStack,
|
||||
|
|
@ -191,36 +252,24 @@ class AnvilResultListener: Listener {
|
|||
// To avoid vanilla, we cancel the event for unit repair
|
||||
event.result = Event.Result.DENY
|
||||
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)
|
||||
if(repairCost == Int.MIN_VALUE) return
|
||||
|
||||
// If not creative middle click...
|
||||
if (event.click != ClickType.MIDDLE) {
|
||||
// We remove what should be removed
|
||||
inventory.setItem(ANVIL_INPUT_LEFT, null)
|
||||
rightItem.amount -= resultAmount
|
||||
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
|
||||
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
|
||||
player.level -= repairCost
|
||||
// And then we give the item manually
|
||||
extractAnvilResult(
|
||||
event, player, inventory,
|
||||
leftItem, 1,
|
||||
rightItem, resultAmount,
|
||||
output, repairCost
|
||||
)
|
||||
}
|
||||
|
||||
// Finally, we add the item to the player
|
||||
if (slotDestination.type == SlotType.CURSOR) {
|
||||
player.setItemOnCursor(output)
|
||||
} else {// We assume SlotType == SlotType.INVENTORY
|
||||
player.inventory.setItem(slotDestination.slot, output)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getUnitRepairCost(inventory: AnvilInventory, player: Player,
|
||||
private fun getUnitRepairCost(
|
||||
inventory: AnvilInventory, player: Player,
|
||||
leftItem: ItemStack, output: ItemStack,
|
||||
resultCopy: ItemStack, resultAmount: Int): Int {
|
||||
resultCopy: ItemStack, resultAmount: Int
|
||||
): Int {
|
||||
if (player.gameMode == GameMode.CREATIVE) return 0
|
||||
|
||||
var repairCost = 0
|
||||
|
|
@ -233,7 +282,7 @@ class AnvilResultListener: Listener {
|
|||
repairCost += ConfigOptions.itemRenameCost
|
||||
|
||||
// Color cost
|
||||
if(it.displayName.contains('§')){
|
||||
if (it.displayName.contains('§')) {
|
||||
repairCost += ConfigOptions.useOfColorCost
|
||||
}
|
||||
}
|
||||
|
|
@ -257,6 +306,51 @@ class AnvilResultListener: Listener {
|
|||
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
|
||||
*/
|
||||
|
|
@ -283,8 +377,7 @@ class AnvilResultListener: Listener {
|
|||
return NO_SLOT
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ class PrepareAnvilListener : Listener {
|
|||
event.result = result
|
||||
|
||||
// TODO forgot about xp config & logic
|
||||
// AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
|
||||
AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, 1)
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,26 +19,27 @@ object AnvilLoreEditUtil {
|
|||
return ConfigOptions.PaperLoreEditNeedPermission && player.hasPermission(LORE_BY_PAPER)
|
||||
}
|
||||
|
||||
private fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? {
|
||||
if(!hasLoreEditByBookPermission(player)) return null
|
||||
fun handleLoreAppendByBook(player: Permissible, first: ItemStack, book: BookMeta): ItemStack? {
|
||||
if (!hasLoreEditByBookPermission(player)) return null
|
||||
|
||||
val result = first.clone()
|
||||
val meta = result.itemMeta
|
||||
//TODO take into account previous lore
|
||||
meta?.lore = book.pages[0].split("\n") //TODO check color if color is enabled
|
||||
result.itemMeta = meta
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? {
|
||||
if(!hasLoreEditByBookPermission(player)) return null
|
||||
fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, second: ItemStack, book: BookMeta): ItemStack? {
|
||||
if (!hasLoreEditByBookPermission(player)) return null
|
||||
|
||||
val meta = first.itemMeta
|
||||
if(meta == null || !meta.hasLore()) return null
|
||||
if (meta == null || !meta.hasLore()) return null
|
||||
|
||||
val bookPage = StringBuilder()
|
||||
meta.lore!!.forEach {
|
||||
if(bookPage.isNotEmpty()) bookPage.append('\n')
|
||||
if (bookPage.isNotEmpty()) bookPage.append('\n')
|
||||
bookPage.append(it)
|
||||
}
|
||||
|
||||
|
|
@ -52,15 +53,16 @@ object AnvilLoreEditUtil {
|
|||
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
|
||||
val meta = second.itemMeta as BookMeta
|
||||
|
||||
var hasContent = false
|
||||
if(meta.hasPages() && meta.pageCount >= 1){
|
||||
if (meta.hasPages() && meta.pageCount >= 1) {
|
||||
// Test if the pages is ok
|
||||
for (page in meta.pages) {
|
||||
if(page.isNotEmpty()) {
|
||||
if (page.isNotEmpty()) {
|
||||
hasContent = true
|
||||
break
|
||||
}
|
||||
|
|
@ -68,22 +70,25 @@ object AnvilLoreEditUtil {
|
|||
}
|
||||
|
||||
// We don't want to "add" the first page is there is content and the first page is empty
|
||||
if(hasContent){
|
||||
if(meta.pages[0].isEmpty()) return null
|
||||
if(ConfigOptions.appendLoreBookAndQuil)
|
||||
if (hasContent) {
|
||||
if (meta.pages[0].isEmpty()) return null
|
||||
if (ConfigOptions.appendLoreBookAndQuil)
|
||||
return true
|
||||
}
|
||||
else if(ConfigOptions.removeLoreBookAndQuil) {
|
||||
return false
|
||||
} else if (ConfigOptions.removeLoreBookAndQuil) {
|
||||
if (!first.hasItemMeta()) return null
|
||||
|
||||
val leftMeta = first.itemMeta!!
|
||||
return if (leftMeta.hasLore()) false
|
||||
else null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
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
|
||||
return if(bookType) handleLoreAppendByBook(player, first, meta)
|
||||
return if (bookType) handleLoreAppendByBook(player, first, meta)
|
||||
else handleLoreRemoveByBook(player, first, second, meta)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue