diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index bb24bbe..f759ba0 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -41,6 +41,8 @@ class AnvilEventListener : Listener { val inventory = event.inventory val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val second = inventory.getItem(ANVIL_INPUT_RIGHT) ?: return + + var anvilCost = 0 if (first.canMergeWith(second)) { // Should find player val player = event.view.player @@ -50,7 +52,8 @@ class AnvilEventListener : Listener { val resultItem = first.clone() resultItem.setEnchantmentsUnsafe(newEnchants) - var anvilCost = calculateCost(first, second, resultItem) + anvilCost = calculatePenalty(first, second, resultItem) + anvilCost+= getRightValues(second, resultItem) if (!first.isBook() && !second.isBook()) { // we only need to be concerned with repair when neither item is a book val repaired = resultItem.repairFrom(first, second) @@ -68,8 +71,8 @@ class AnvilEventListener : Listener { if(!it.displayName.contentEquals(inventory.renameText)){ it.setDisplayName(inventory.renameText) anvilCost += ConfigOptions.itemRenameCost + resultItem.itemMeta = it } - resultItem.itemMeta = it } if (ConfigOptions.limitRepairCost) { @@ -112,18 +115,37 @@ class AnvilEventListener : Listener { } /** - * Function to calculate most of the xp requirement for the anvil fuse - * Change result work penalty for future use + * Function to calculate work penalty of anvil work + * Also change result work penalty */ - private fun calculateCost(left: ItemStack, right: ItemStack, result: ItemStack): Int{ + private fun calculatePenalty(left: ItemStack, right: ItemStack, result: ItemStack): Int{ // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation // Calculate work penality val leftPenality = (left.itemMeta as? Repairable)?.repairCost ?: 0 val rightPenality = (right.itemMeta as? Repairable)?.repairCost ?: 0 + // Try to set work penality for the result item + result.itemMeta?.let { + (it as? Repairable)?.repairCost = leftPenality*2+1 + result.itemMeta = it + } + + UnsafeEnchants.log("Calculated penality: " + + "leftPenality: $leftPenality, " + + "rightPenality: $rightPenality, " + + "result penality: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}") + + return leftPenality + rightPenality + } + + /** + * Function to calculate right enchantment values + * it include enchantment placed on final item and conflicting enchantment + */ + private fun getRightValues(right: ItemStack, result:ItemStack) : Int { // Calculate right value and illegal enchant penalty - var rightValue = 0 var illegalPenalty = 0 + var rightValue = 0 val rightIsFormBook = right.isBook() val resultEnchs = result.findEnchantments() @@ -147,25 +169,14 @@ class AnvilEventListener : Listener { val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, rightIsFormBook) val value = resultLevel * enchantmentMultiplier UnsafeEnchants.log("Value for ${enchantment.key.enchantmentName} level ${enchantment.value} is $value") - rightValue+=value + rightValue += value } - - // Try to set work penality for the result item - result.itemMeta?.let { - (it as? Repairable)?.repairCost = leftPenality*2+1 - result.itemMeta = it - } - - UnsafeEnchants.log("Calculated cost: " + - "leftPenality: $leftPenality, " + - "rightPenality: $rightPenality, " + + UnsafeEnchants.log("Calculated right values: " + "rightValue: $rightValue, " + - "illegalPenalty: $illegalPenalty," + - "result penality: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}") + "illegalPenalty: $illegalPenalty") - // We are missing [Renaming Cost] + [Refilling Durability] but it will be handled later - return rightValue + leftPenality + rightPenality + illegalPenalty + return rightValue + illegalPenalty } } diff --git a/src/main/kotlin/io/delilaheve/UnsafeEnchants.kt b/src/main/kotlin/io/delilaheve/UnsafeEnchants.kt index b8c925c..3abcf12 100644 --- a/src/main/kotlin/io/delilaheve/UnsafeEnchants.kt +++ b/src/main/kotlin/io/delilaheve/UnsafeEnchants.kt @@ -6,8 +6,8 @@ import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.plugin.java.JavaPlugin import xyz.alexcrea.group.EnchantConflictManager import xyz.alexcrea.group.ItemGroupManager -import xyz.alexcrea.group.util.Metrics -import xyz.alexcrea.group.util.Metrics.SimplePie +import xyz.alexcrea.util.Metrics +import xyz.alexcrea.util.Metrics.SimplePie import java.io.File import java.io.FileReader @@ -29,15 +29,20 @@ class UnsafeEnchants : JavaPlugin() { const val bypassLevelPermission = "ue.bypass.level" // Item Grouping Configuration file name - const val itemGroupingConfigName = "item_groups.yml" + const val itemGroupingConfigFilePath = "item_groups.yml" // Conflict Configuration file name - const val enchantConflicConfigName = "enchant_conflict.yml" + const val enchantConflicConfigFilePath = "enchant_conflict.yml" + // Unit Repair Configuration file name + const val unitRepairFilePath = "unit_repair_item.yml" // Current plugin instance lateinit var instance: UnsafeEnchants // Current item grouping configuration instance lateinit var conflictManager: EnchantConflictManager + // Configuration for unit repair + lateinit var unitRepairConfig: YamlConfiguration + /** * Logging handler */ @@ -60,17 +65,20 @@ class UnsafeEnchants : JavaPlugin() { addCustomMetric(metric) // Load material grouping config - val itemGroupConfig = reloadResource(itemGroupingConfigName) ?: return + val itemGroupConfig = reloadResource(itemGroupingConfigFilePath) ?: return // Read material groups from config val itemGroupsManager = ItemGroupManager() itemGroupsManager.prepareGroups(itemGroupConfig) // Load enchantment conflicts config - val conflictConfig = reloadResource(enchantConflicConfigName) ?: return + val conflictConfig = reloadResource(enchantConflicConfigFilePath) ?: return // Read conflicts from config and material group manager conflictManager = EnchantConflictManager() conflictManager.prepareConflicts(conflictConfig,itemGroupsManager) + // Load unit repair config + unitRepairConfig = reloadResource(unitRepairFilePath) ?: return + server.pluginManager.registerEvents( AnvilEventListener(), this @@ -82,16 +90,12 @@ class UnsafeEnchants : JavaPlugin() { metric.addCustomChart(SimplePie("item_rename_cost") { ConfigOptions.itemRenameCost.toString() }) - println("item_rename_cost: ${ConfigOptions.itemRenameCost}") metric.addCustomChart(SimplePie("item_repair_cost") { ConfigOptions.itemRepairCost.toString() }) - println("item_repair_cost: ${ConfigOptions.itemRepairCost}") metric.addCustomChart(SimplePie("sacrifice_illegal_enchant_cost") { ConfigOptions.sacrificeIllegalCost.toString() }) - println("sacrifice_illegal_enchant_cost: ${ConfigOptions.sacrificeIllegalCost}") - } private fun reloadResource(resourceName: String, diff --git a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt index 1f8f9c8..bd46167 100644 --- a/src/main/kotlin/io/delilaheve/util/ItemUtil.kt +++ b/src/main/kotlin/io/delilaheve/util/ItemUtil.kt @@ -25,13 +25,6 @@ object ItemUtil { */ 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] */ @@ -108,5 +101,5 @@ object ItemUtil { */ fun ItemStack.canMergeWith( other: ItemStack - ) = type == other.type || (canHoldEnchants() && other.isEnchantedBook()) + ) = type == other.type || (other.isEnchantedBook()) } diff --git a/src/main/kotlin/xyz/alexcrea/group/util/Metrics.java b/src/main/kotlin/xyz/alexcrea/util/Metrics.java similarity index 99% rename from src/main/kotlin/xyz/alexcrea/group/util/Metrics.java rename to src/main/kotlin/xyz/alexcrea/util/Metrics.java index da923c2..f8a1a9b 100644 --- a/src/main/kotlin/xyz/alexcrea/group/util/Metrics.java +++ b/src/main/kotlin/xyz/alexcrea/util/Metrics.java @@ -12,7 +12,7 @@ * * Violations will result in a ban of your plugin and account from bStats. */ -package xyz.alexcrea.group.util; +package xyz.alexcrea.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; diff --git a/src/main/kotlin/xyz/alexcrea/util/UnitRepairUtil.kt b/src/main/kotlin/xyz/alexcrea/util/UnitRepairUtil.kt new file mode 100644 index 0000000..ad57d4c --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/util/UnitRepairUtil.kt @@ -0,0 +1,55 @@ +package xyz.alexcrea.util + +import io.delilaheve.UnsafeEnchants +import org.bukkit.configuration.ConfigurationSection +import org.bukkit.inventory.ItemStack + +object UnitRepairUtil { + + // Default value for user set default unit repair % + private const val DEFAULT_DEFAULT_UNIT_REPAIR = 0.25 + + /** + * Get the % of repair by unit [other] will do to this [ItemStack]. + * null if can't unit repaired by [other] + */ + fun ItemStack.getRepair( + other: ItemStack + ): Double? { + val config = UnsafeEnchants.unitRepairConfig + // Get configuration section if exist + val otherName = other.type.name.uppercase() + var section = config.getConfigurationSection(otherName) + if(section == null){ + section = config.getConfigurationSection(otherName.lowercase()) + if(section == null) return null + } + // Get repair amount + var userDefault = config.getDouble("default_repair_amount",DEFAULT_DEFAULT_UNIT_REPAIR) + if(userDefault <= 0){ + userDefault = DEFAULT_DEFAULT_UNIT_REPAIR + } + + return getRepairAmount(this,section,userDefault) + } + + /** + * Get the item % repaired by this configuration section of a unit repair. + * null if not found. + * If value is set to less than or equal to 0 then it will be set to default + */ + private fun getRepairAmount(item: ItemStack, section: ConfigurationSection, default: Double): Double?{ + val itemName = item.type.name.uppercase() + val repairValue = if(section.isDouble(itemName)){ + section.getDouble(itemName) + }else if(section.isDouble(itemName.lowercase())){ + section.getDouble(itemName.lowercase()) + }else{ + return null + } + if(repairValue <= 0) + return default + return repairValue + } + +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 19a97ab..005dca3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -13,11 +13,17 @@ limit_repair_value: 39 # The anvil will still visually display "too expensive" however the action will be completable remove_repair_limit: false -# Value added to the anvil when the item durability increase +# Value added to the anvil when the item is repaired by another item of the same type # # Valid range of 0 - 255 item_repair_cost: 2 +# Value added to the anvil when the item is repaired by an "unit" +# For example, a diamond on a diamond sword +# +# Valid range of 0 - 255 +unit_repair_cost: 1 + # Value added to the anvil when the item is renamed # # Valid range of 0 - 255 diff --git a/src/main/resources/unit_repair_item.yml b/src/main/resources/unit_repair_item.yml new file mode 100644 index 0000000..503fa1d --- /dev/null +++ b/src/main/resources/unit_repair_item.yml @@ -0,0 +1 @@ +#TODO \ No newline at end of file