mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-23 16:16:17 +02:00
122 lines
4.1 KiB
Kotlin
122 lines
4.1 KiB
Kotlin
package io.delilaheve.util
|
|
|
|
import io.delilaheve.UnsafeEnchants
|
|
import io.delilaheve.util.EnchantmentUtil.calculateValue
|
|
import org.bukkit.Material.BOOK
|
|
import org.bukkit.Material.ENCHANTED_BOOK
|
|
import org.bukkit.enchantments.Enchantment
|
|
import org.bukkit.inventory.ItemStack
|
|
import org.bukkit.inventory.meta.Damageable
|
|
import org.bukkit.inventory.meta.EnchantmentStorageMeta
|
|
import org.bukkit.inventory.meta.ItemMeta
|
|
import org.bukkit.inventory.meta.Repairable
|
|
import kotlin.math.min
|
|
|
|
/**
|
|
* Item manipulation utilities
|
|
*/
|
|
object ItemUtil {
|
|
|
|
/**
|
|
* Determine the value of an item for repair
|
|
*
|
|
* ToDo - use native repair cost
|
|
*/
|
|
val ItemStack.repairCost: Int
|
|
get() {
|
|
val nativeCost = (itemMeta as? Repairable)?.repairCost
|
|
val pluginCost = findEnchantments().calculateValue(isBook())
|
|
UnsafeEnchants.log("Native Cost: $nativeCost; Plugin Cost: $pluginCost")
|
|
return nativeCost.takeIf { it != 0 } ?: pluginCost
|
|
}
|
|
|
|
/**
|
|
* Check if this [ItemStack] is a [BOOK] or [ENCHANTED_BOOK]
|
|
*/
|
|
fun ItemStack.isBook() = type in listOf(BOOK, ENCHANTED_BOOK)
|
|
|
|
/**
|
|
* Check if this [ItemStack] is an [ENCHANTED_BOOK]
|
|
*/
|
|
private fun ItemStack.isEnchantedBook() = type == ENCHANTED_BOOK
|
|
|
|
/**
|
|
* Determine if this [ItemStack] can hold enchants, this should be sufficient for
|
|
* detecting if an item is a tool/armour/etc... and not a carrot/potato/etc...
|
|
*/
|
|
private fun ItemStack.canHoldEnchants() = Enchantment.values()
|
|
.any { it.canEnchantItem(this) }
|
|
|
|
/**
|
|
* Find the enchantment map for this [ItemStack] and return it as a [MutableMap]
|
|
*/
|
|
fun ItemStack.findEnchantments() = if (isBook()) {
|
|
(itemMeta as? EnchantmentStorageMeta)?.storedEnchants ?: emptyMap()
|
|
} else {
|
|
itemMeta?.enchants ?: emptyMap()
|
|
}
|
|
|
|
/**
|
|
* Apply an [enchantments] map to this [ItemStack]
|
|
*/
|
|
fun ItemStack.setEnchantmentsUnsafe(enchantments: Map<Enchantment, Int>) {
|
|
if (isBook()) {
|
|
/* For some god-forsaken reason, item meta is not mutable
|
|
* so, we have to get the instance, modify it, then set it
|
|
* back to the item... #BecauseMinecraft */
|
|
val bookMeta = (itemMeta as? EnchantmentStorageMeta)
|
|
bookMeta?.replaceEnchants(enchantments)
|
|
itemMeta = bookMeta
|
|
} else {
|
|
itemMeta?.enchants?.forEach { (enchant, _) ->
|
|
removeEnchantment(enchant)
|
|
}
|
|
addUnsafeEnchantments(enchantments)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply an [enchantments] map to this book
|
|
*/
|
|
private fun EnchantmentStorageMeta.replaceEnchants(
|
|
enchantments: Map<Enchantment, Int>
|
|
) {
|
|
storedEnchants.forEach { (enchant, _) ->
|
|
removeStoredEnchant(enchant)
|
|
}
|
|
enchantments.forEach { (enchant, level) ->
|
|
val added = addStoredEnchant(enchant, level, true)
|
|
UnsafeEnchants.log("${enchant.key} added to item? $added")
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set this [ItemStack]s durability from a combination of the
|
|
* [first] and [second] item's durability values
|
|
*/
|
|
fun ItemStack.repairFrom(
|
|
first: ItemStack,
|
|
second: ItemStack
|
|
) {
|
|
(itemMeta as? Damageable)?.let {
|
|
val durability = type.maxDurability.toInt()
|
|
val firstDamage = (first.itemMeta as? Damageable)?.damage ?: 0
|
|
val firstDurability = durability - firstDamage
|
|
val secondDamage = (second.itemMeta as? Damageable)?.damage ?: 0
|
|
val secondDurability = durability - secondDamage
|
|
val combinedDurability = firstDurability + secondDurability
|
|
val newDurability = min(combinedDurability, durability)
|
|
it.damage = durability - newDurability
|
|
itemMeta = it as ItemMeta
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check that this [ItemStack] can merge with the [other]
|
|
*
|
|
* The two items should either be the same type, or, the [other] is a book
|
|
*/
|
|
fun ItemStack.canMergeWith(
|
|
other: ItemStack
|
|
) = type == other.type || (canHoldEnchants() && other.isEnchantedBook())
|
|
}
|