mirror of
https://github.com/alexcrea/CustomAnvil.git
synced 2026-06-24 00:26:16 +02:00
Initial commit
This commit is contained in:
commit
e53f9cc88c
14 changed files with 939 additions and 0 deletions
124
src/main/kotlin/io/delilaheve/util/ConfigOptions.kt
Normal file
124
src/main/kotlin/io/delilaheve/util/ConfigOptions.kt
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
package io.delilaheve.util
|
||||
|
||||
import io.delilaheve.UnsafeEnchants
|
||||
import io.delilaheve.util.EnchantmentUtil.enchantmentName
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
|
||||
/**
|
||||
* Config option accessors
|
||||
*/
|
||||
object ConfigOptions {
|
||||
|
||||
// Path for default enchantment limits
|
||||
private const val DEFAULT_LIMIT_PATH = "default_limit"
|
||||
// Path for allowing unsafe enchants
|
||||
private const val ALLOW_UNSAFE_PATH = "allow_unsafe"
|
||||
// Path for limiting repair cost
|
||||
private const val LIMIT_REPAIR_COST = "limit_repair_cost"
|
||||
// Path for removing repair cost limits
|
||||
private const val REMOVE_REPAIR_LIMIT = "remove_repair_limit"
|
||||
// Root path for enchantment limits
|
||||
private const val ENCHANT_LIMIT_ROOT = "enchant_limits"
|
||||
// Root path for enchantment values
|
||||
private const val ENCHANT_VALUES_ROOT = "enchant_values"
|
||||
// Keys for specific enchantment values
|
||||
private const val KEY_BOOK = "book"
|
||||
private const val KEY_ITEM = "item"
|
||||
// Debug logging toggle path
|
||||
private const val DEBUG_LOGGING = "debug_log"
|
||||
|
||||
// Default value for enchantment limits
|
||||
private const val DEFAULT_ENCHANT_LIMIT = 10
|
||||
// Default value for allowing unsafe enchantments
|
||||
private const val DEFAULT_ALLOW_UNSAFE = true
|
||||
// Default value for limiting repair cost
|
||||
private const val DEFAULT_LIMIT_REPAIR = true
|
||||
// Default for removing repair cost limits
|
||||
private const val DEFAULT_REMOVE_LIMIT = false
|
||||
// Valid range for an enchantment limit
|
||||
private val ENCHANT_LIMIT_RANGE = 1..255
|
||||
// Default value for an enchantment multiplier
|
||||
private const val DEFAULT_ENCHANT_VALUE = 0
|
||||
// Default value for debug logging
|
||||
private const val DEFAULT_DEBUG_LOG = false
|
||||
|
||||
/**
|
||||
* Default enchantment limit
|
||||
*/
|
||||
private val defaultEnchantLimit: Int
|
||||
get() {
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to allow unsafe enchantments
|
||||
*/
|
||||
val allowUnsafe: Boolean
|
||||
get() {
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getBoolean(ALLOW_UNSAFE_PATH, DEFAULT_ALLOW_UNSAFE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to limit repair costs to the vanilla limit
|
||||
*/
|
||||
val limitRepairCost: Boolean
|
||||
get() {
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getBoolean(LIMIT_REPAIR_COST, DEFAULT_LIMIT_REPAIR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to remove repair cost limit
|
||||
*/
|
||||
val removeRepairLimit: Boolean
|
||||
get() {
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getBoolean(REMOVE_REPAIR_LIMIT, DEFAULT_REMOVE_LIMIT)
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to show debug logging
|
||||
*/
|
||||
val debugLog: Boolean
|
||||
get() {
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getBoolean(DEBUG_LOGGING, DEFAULT_DEBUG_LOG)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given [enchantment]'s limit
|
||||
*/
|
||||
fun enchantLimit(enchantment: Enchantment): Int {
|
||||
val path = "${ENCHANT_LIMIT_ROOT}.${enchantment.enchantmentName}"
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getInt(path, defaultEnchantLimit)
|
||||
.takeIf { it in ENCHANT_LIMIT_RANGE }
|
||||
?: defaultEnchantLimit
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the appropriate [enchantment]'s value dependent on whether
|
||||
* it's source [isFromBook]
|
||||
*/
|
||||
fun enchantmentValue(
|
||||
enchantment: Enchantment,
|
||||
isFromBook: Boolean
|
||||
): Int {
|
||||
val typeKey = if (isFromBook) KEY_BOOK else KEY_ITEM
|
||||
val path = "${ENCHANT_VALUES_ROOT}.${enchantment.enchantmentName}.$typeKey"
|
||||
return UnsafeEnchants.instance
|
||||
.config
|
||||
.getInt(path, DEFAULT_ENCHANT_VALUE)
|
||||
.takeIf { it >= DEFAULT_ENCHANT_VALUE }
|
||||
?: DEFAULT_ENCHANT_VALUE
|
||||
}
|
||||
|
||||
}
|
||||
64
src/main/kotlin/io/delilaheve/util/EnchantmentUtil.kt
Normal file
64
src/main/kotlin/io/delilaheve/util/EnchantmentUtil.kt
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
package io.delilaheve.util
|
||||
|
||||
import io.delilaheve.UnsafeEnchants
|
||||
import org.bukkit.enchantments.Enchantment
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* Enchantment manipulation utilities
|
||||
*/
|
||||
object EnchantmentUtil {
|
||||
|
||||
val Enchantment.enchantmentName: String
|
||||
get() = key.key
|
||||
/**
|
||||
* Combine 2 sets of enchantments according to our configuration
|
||||
*/
|
||||
fun MutableMap<Enchantment, Int>.combineWith(
|
||||
other: MutableMap<Enchantment, Int>
|
||||
) = mutableMapOf<Enchantment, Int>().apply {
|
||||
putAll(this@combineWith)
|
||||
other.forEach { (enchantment, level) ->
|
||||
when {
|
||||
// Enchantment not yet in result list
|
||||
!containsKey(enchantment) -> {
|
||||
// Add the enchantment if it doesn't have conflicts, or, if we're allowing unsafe enchantments
|
||||
if (!keys.any { enchantment.conflictsWith(it) } || ConfigOptions.allowUnsafe) {
|
||||
this[enchantment] = level
|
||||
}
|
||||
}
|
||||
// Enchantment already in result list...
|
||||
else -> when {
|
||||
// ... and they're not the same level
|
||||
this[enchantment] != other[enchantment] -> {
|
||||
val newLevel = max(this[enchantment] ?: 0, other[enchantment] ?: 0)
|
||||
// apply the greater of the two if non-zero
|
||||
if (newLevel > 0) { this[enchantment] = newLevel }
|
||||
}
|
||||
// ... and they're the same level
|
||||
else -> {
|
||||
// try to increase the enchantment level by 1
|
||||
var newLevel = this[enchantment]?.plus(1) ?: 0
|
||||
val maxLevel = ConfigOptions.enchantLimit(enchantment)
|
||||
newLevel = min(newLevel, maxLevel)
|
||||
if (newLevel > 0) { this[enchantment] = newLevel }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the value of a set of enchantments
|
||||
*/
|
||||
fun Map<Enchantment, Int>.calculateValue(
|
||||
fromBook: Boolean
|
||||
) = entries.sumOf { (enchantment, level) ->
|
||||
val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment, fromBook)
|
||||
val value = level * enchantmentMultiplier
|
||||
UnsafeEnchants.log("Value for ${enchantment.enchantmentName} is $value")
|
||||
value
|
||||
}
|
||||
|
||||
}
|
||||
83
src/main/kotlin/io/delilaheve/util/ItemUtil.kt
Normal file
83
src/main/kotlin/io/delilaheve/util/ItemUtil.kt
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package io.delilaheve.util
|
||||
|
||||
import io.delilaheve.UnsafeEnchants
|
||||
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.EnchantmentStorageMeta
|
||||
|
||||
/**
|
||||
* Item manipulation utilities
|
||||
*/
|
||||
object ItemUtil {
|
||||
|
||||
/**
|
||||
* 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")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue