alpha version up & cleanup code.

This commit is contained in:
alexcrea 2024-03-31 00:59:50 +01:00
parent 1b83c8db81
commit 00fba2f4b0
40 changed files with 893 additions and 718 deletions

View file

@ -39,9 +39,10 @@ class AnvilEventListener : Listener {
private const val ANVIL_INPUT_LEFT = 0
private const val ANVIL_INPUT_RIGHT = 1
private const val ANVIL_OUTPUT_SLOT = 2
// static slot container
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT,0)
private val CURSOR_SLOT = SlotContainer(SlotType.CURSOR,0)
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT, 0)
private val CURSOR_SLOT = SlotContainer(SlotType.CURSOR, 0)
}
/**
@ -55,15 +56,15 @@ class AnvilEventListener : Listener {
// Should find player
val player = event.view.player
if(!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
// Test rename lonely item
if(second == null){
if (second == null) {
val resultItem = first.clone()
var anvilCost = handleRename(resultItem, inventory)
// Test/stop if nothing changed.
if(first == resultItem){
if (first == resultItem) {
CustomAnvil.log("no right item, But input is same as output")
event.result = null
return
@ -71,7 +72,7 @@ class AnvilEventListener : Listener {
// We don't manually set item here as vanilla do it (renaming)
//event.result = null
anvilCost+= calculatePenalty(first,null,resultItem)
anvilCost += calculatePenalty(first, null, resultItem)
handleAnvilXp(inventory, event, anvilCost)
return
@ -91,19 +92,19 @@ class AnvilEventListener : Listener {
if (!first.isEnchantedBook() && !second.isEnchantedBook()) {
// we only need to be concerned with repair when neither item is a book
val repaired = resultItem.repairFrom(first, second)
anvilCost += if(repaired) ConfigOptions.itemRepairCost else 0
anvilCost += if (repaired) ConfigOptions.itemRepairCost else 0
}
// Test/stop if nothing changed.
if(first == resultItem){
if (first == resultItem) {
CustomAnvil.log("Mergable with second, But input is same as output")
event.result = null
return
}
// As calculatePenalty edit result, we need to calculate penalty after checking equality
anvilCost+= calculatePenalty(first, second, resultItem)
anvilCost += calculatePenalty(first, second, resultItem)
// Calculate rename cost
anvilCost+= handleRename(resultItem, inventory)
anvilCost += handleRename(resultItem, inventory)
// Finally, we set result
event.result = resultItem
@ -114,19 +115,19 @@ class AnvilEventListener : Listener {
// Test for unit repair
val unitRepairAmount = first.getRepair(second)
if(unitRepairAmount != null){
if (unitRepairAmount != null) {
val resultItem = first.clone()
var anvilCost = handleRename(resultItem, inventory)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if(repairAmount > 0){
anvilCost += repairAmount*ConfigOptions.unitRepairCost
if (repairAmount > 0) {
anvilCost += repairAmount * ConfigOptions.unitRepairCost
}
// We do not care about right item penalty for unit repair
anvilCost+= calculatePenalty(first,null,resultItem)
anvilCost += calculatePenalty(first, null, resultItem)
// Test/stop if nothing changed.
if(first == resultItem){
if (first == resultItem) {
CustomAnvil.log("unit repair, But input is same as output")
event.result = null
return
@ -134,16 +135,16 @@ class AnvilEventListener : Listener {
event.result = resultItem
handleAnvilXp(inventory, event, anvilCost)
}else{
} else {
CustomAnvil.log("no anvil fuse type found")
event.result = null
}
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int{
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int {
// Rename item and add renaming cost
resultItem.itemMeta?.let {
if(!it.displayName.contentEquals(inventory.renameText)){
if (!it.displayName.contentEquals(inventory.renameText)) {
it.setDisplayName(inventory.renameText)
resultItem.itemMeta = it
return ConfigOptions.itemRenameCost
@ -158,9 +159,11 @@ class AnvilEventListener : Listener {
@EventHandler(ignoreCancelled = true)
fun anvilExtractionCheck(event: InventoryClickEvent) {
val player = event.whoClicked as? Player ?: return
if(!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
val inventory = event.inventory as? AnvilInventory ?: return
if (event.rawSlot != ANVIL_OUTPUT_SLOT) { return }
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
return
}
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
@ -172,110 +175,117 @@ class AnvilEventListener : Listener {
|| (unitRepairResult != null)
// True if there was no change or not allowed
if((output == inventory.getItem(ANVIL_INPUT_LEFT))
|| !allowed){
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))
|| !allowed
) {
event.result = Event.Result.DENY
return
}
if(rightItem == null){
if (rightItem == null) {
event.result = Event.Result.ALLOW
return
}
if(canMerge){
if (canMerge) {
event.result = Event.Result.ALLOW
}else if(unitRepairResult != null){
onUnitRepairExtract(leftItem, rightItem, output,
unitRepairResult, event, player, inventory)
} else if (unitRepairResult != null) {
onUnitRepairExtract(
leftItem, rightItem, output,
unitRepairResult, event, player, inventory
)
return
}
}
private fun onUnitRepairExtract(leftItem: ItemStack,
rightItem: ItemStack,
output: ItemStack,
unitRepairResult: Double,
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory){
private fun onUnitRepairExtract(
leftItem: ItemStack,
rightItem: ItemStack,
output: ItemStack,
unitRepairResult: Double,
event: InventoryClickEvent,
player: Player,
inventory: AnvilInventory
) {
val resultCopy = leftItem.clone()
val resultAmount = resultCopy.unitRepair(
rightItem.amount, unitRepairResult)
rightItem.amount, unitRepairResult
)
// 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
val slotDestination = getActionSlot(event, player)
if (slotDestination.type == SlotType.NO_SLOT) return
// Test repair cost
var repairCost = 0
if(player.gameMode != GameMode.CREATIVE){
if (player.gameMode != GameMode.CREATIVE) {
// Get repairCost
leftItem.itemMeta?.let { leftMeta ->
val leftName = leftMeta.displayName
output.itemMeta?.let {
if(!leftName.contentEquals(it.displayName)){
repairCost+= ConfigOptions.itemRenameCost
if (!leftName.contentEquals(it.displayName)) {
repairCost += ConfigOptions.itemRenameCost
}
}
}
repairCost+= calculatePenalty(leftItem,null,resultCopy)
repairCost+= resultAmount*ConfigOptions.unitRepairCost
repairCost += calculatePenalty(leftItem, null, resultCopy)
repairCost += resultAmount * ConfigOptions.unitRepairCost
if((inventory.maximumRepairCost < repairCost)
|| (player.level < repairCost)) return
if ((inventory.maximumRepairCost < repairCost)
|| (player.level < repairCost)
) return
}
// If not creative middle click...
if(event.click != ClickType.MIDDLE){
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_INPUT_LEFT, null)
rightItem.amount -= resultAmount
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
inventory.setItem(ANVIL_OUTPUT_SLOT, null)
player.level-= repairCost
player.level -= repairCost
}
// Finally, we add the item to the player
if(slotDestination.type == SlotType.CURSOR){
if (slotDestination.type == SlotType.CURSOR) {
player.setItemOnCursor(output)
}else{// We assume SlotType == SlotType.INVENTORY
player.inventory.setItem(slotDestination.slot,output)
} else {// We assume SlotType == SlotType.INVENTORY
player.inventory.setItem(slotDestination.slot, output)
}
}
/**
* Get the destination slot or "NO_SLOT" slot container if there is no slot available
*/
private fun getActionSlot(event: InventoryClickEvent, player: Player): SlotContainer{
if(event.isShiftClick){
private fun getActionSlot(event: InventoryClickEvent, player: Player): SlotContainer {
if (event.isShiftClick) {
val inventory = player.inventory
val firstEmpty = inventory.firstEmpty()
if(firstEmpty == -1){
val firstEmpty = inventory.firstEmpty()
if (firstEmpty == -1) {
return NO_SLOT
}
//check hotbare full
var slotIndex = 8
while(slotIndex >= 0 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)){
while (slotIndex >= 0 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)) {
slotIndex--
}
if(slotIndex >= 0){
return SlotContainer(SlotType.INVENTORY,slotIndex)
if (slotIndex >= 0) {
return SlotContainer(SlotType.INVENTORY, slotIndex)
}
slotIndex = 35 //4*9 - 1 (max of player inventory)
while(slotIndex >= 9 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)){
while (slotIndex >= 9 && ((inventory.getItem(slotIndex)?.type ?: Material.AIR) != Material.AIR)) {
slotIndex--
}
if(slotIndex < 9){
if (slotIndex < 9) {
return NO_SLOT
}
return SlotContainer(SlotType.INVENTORY,slotIndex)
}else{
if(player.itemOnCursor.type != Material.AIR){
return SlotContainer(SlotType.INVENTORY, slotIndex)
} else {
if (player.itemOnCursor.type != Material.AIR) {
return NO_SLOT
}
return CURSOR_SLOT
@ -286,24 +296,29 @@ class AnvilEventListener : Listener {
* Function to calculate work penalty of anvil work
* Also change result work penalty
*/
private fun calculatePenalty(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 penalty
val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0
val rightPenalty =
if(right == null){ 0 }
else{ (right.itemMeta as? Repairable)?.repairCost ?: 0 }
if (right == null) {
0
} else {
(right.itemMeta as? Repairable)?.repairCost ?: 0
}
// Try to set work penalty for the result item
result.itemMeta?.let {
(it as? Repairable)?.repairCost = leftPenalty*2+1
(it as? Repairable)?.repairCost = leftPenalty * 2 + 1
result.itemMeta = it
}
CustomAnvil.log("Calculated penalty: " +
"leftPenalty: $leftPenalty, " +
"rightPenalty: $rightPenalty, " +
"result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}")
CustomAnvil.log(
"Calculated penalty: " +
"leftPenalty: $leftPenalty, " +
"rightPenalty: $rightPenalty, " +
"result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}"
)
return leftPenalty + rightPenalty
}
@ -312,7 +327,7 @@ class AnvilEventListener : Listener {
* Function to calculate right enchantment values
* it include enchantment placed on final item and conflicting enchantment
*/
private fun getRightValues(right: ItemStack, result:ItemStack) : Int {
private fun getRightValues(right: ItemStack, result: ItemStack): Int {
// Calculate right value and illegal enchant penalty
var illegalPenalty = 0
var rightValue = 0
@ -323,12 +338,16 @@ class AnvilEventListener : Listener {
for (enchantment in right.findEnchantments()) {
// count enchant as illegal enchant if it conflicts with another enchant or not in result
if((enchantment.key !in resultEnchsKeys)){
if ((enchantment.key !in resultEnchsKeys)) {
resultEnchsKeys.add(enchantment.key)
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(resultEnchsKeys,result.type,enchantment.key)
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(
resultEnchsKeys,
result.type,
enchantment.key
)
resultEnchsKeys.remove(enchantment.key)
if(ConflictType.BIG_CONFLICT == conflictType){
if (ConflictType.BIG_CONFLICT == conflictType) {
illegalPenalty += ConfigOptions.sacrificeIllegalCost
}
continue
@ -342,9 +361,11 @@ class AnvilEventListener : Listener {
rightValue += value
}
CustomAnvil.log("Calculated right values: " +
"rightValue: $rightValue, " +
"illegalPenalty: $illegalPenalty")
CustomAnvil.log(
"Calculated right values: " +
"rightValue: $rightValue, " +
"illegalPenalty: $illegalPenalty"
)
return rightValue + illegalPenalty
}
@ -352,15 +373,16 @@ class AnvilEventListener : Listener {
/**
* Display xp needed for the work on the anvil inventory
*/
private fun handleAnvilXp(inventory: AnvilInventory,
event: PrepareAnvilEvent,
anvilCost: Int){
private fun handleAnvilXp(
inventory: AnvilInventory,
event: PrepareAnvilEvent,
anvilCost: Int
) {
// Test repair cost limit
val finalAnvilCost: Int
if (ConfigOptions.limitRepairCost) {
finalAnvilCost = min(anvilCost, ConfigOptions.limitRepairValue)
}else{
finalAnvilCost = anvilCost
val finalAnvilCost = if (ConfigOptions.limitRepairCost) {
min(anvilCost, ConfigOptions.limitRepairValue)
} else {
anvilCost
}
/* Because Minecraft likes to have the final say in the repair cost displayed
@ -383,7 +405,7 @@ class AnvilEventListener : Listener {
private class SlotContainer(val type: SlotType, val slot: Int)
private enum class SlotType{
private enum class SlotType {
CURSOR,
INVENTORY,
NO_SLOT

View file

@ -24,17 +24,22 @@ class CustomAnvil : JavaPlugin() {
// Permission string required to use the plugin's features
const val affectedByPluginPermission = "ca.affected"
// Permission string required to bypass enchantment conflicts test
const val bypassFusePermission = "ca.bypass.fuse"
// Permission string required to bypass enchantment conflicts test
const val bypassLevelPermission = "ca.bypass.level"
// Permission string required to reload the config
const val commandReloadPermission = "ca.command.reload"
// Permission string required to edit the plugin's config
const val editConfigPermission = "ca.config.edit"
// Command Name to reload the config
const val commandReloadName = "anvilconfigreload"
// Test command name
const val commandTestName = "customanvilconfig"
@ -71,7 +76,7 @@ class CustomAnvil : JavaPlugin() {
// Disable old plugin name if exist
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
if(potentialPlugin != null){
if (potentialPlugin != null) {
Bukkit.getPluginManager().disablePlugin(potentialPlugin)
logger.warning("An old version of this plugin was detected")
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
@ -83,7 +88,7 @@ class CustomAnvil : JavaPlugin() {
// Load config
val success = ConfigHolder.loadConfig()
if(!success) return
if (!success) return
// Load metrics
val metric = Metrics(this, bstatsPluginId)
@ -98,26 +103,28 @@ class CustomAnvil : JavaPlugin() {
)
}
fun reloadResource(resourceName: String,
hardFailSafe:Boolean = true): YamlConfiguration?{
fun reloadResource(
resourceName: String,
hardFailSafe: Boolean = true
): YamlConfiguration? {
// Save default resource
val file = File(dataFolder,resourceName)
if(!file.exists()){
saveResource(resourceName,false)
val file = File(dataFolder, resourceName)
if (!file.exists()) {
saveResource(resourceName, false)
}
// Load resource
val yamlConfig = YamlConfiguration()
try {
val configReader = FileReader(file)
yamlConfig.load(configReader)
} catch (test: Exception){
if(hardFailSafe){
} catch (test: Exception) {
if (hardFailSafe) {
// This is important and may impact gameplay if it does not load.
// Failsafe is to stop the plugin
logger.severe("Resource $resourceName Could not be load or reload.")
logger.severe("Disabling plugin.")
Bukkit.getPluginManager().disablePlugin(this)
}else{
} else {
logger.warning("Resource $resourceName Could not be load or reload.")
}
return null

View file

@ -12,67 +12,94 @@ object ConfigOptions {
// Path for default enchantment limits
private const val DEFAULT_LIMIT_PATH = "default_limit"
// Path for limiting repair cost
const val LIMIT_REPAIR_COST = "limit_repair_cost"
// Path for repair value limit
const val LIMIT_REPAIR_VALUE = "limit_repair_value"
// Path for level cost on item repair
const val ITEM_REPAIR_COST = "item_repair_cost"
// Path for level cost on unit repair
const val UNIT_REPAIR_COST = "unit_repair_cost"
// Path for level cost on item renaming
const val ITEM_RENAME_COST = "item_rename_cost"
// Path for level cost on illegal enchantment on sacrifice
const val SACRIFICE_ILLEGAL_COST = "sacrifice_illegal_enchant_cost"
// Path for removing repair cost limits
const val REMOVE_REPAIR_LIMIT = "remove_repair_limit"
// Root path for enchantment limits
const val ENCHANT_LIMIT_ROOT = "enchant_limits"
// Root path for enchantment values
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"
// Debug verbose logging toggle path
private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose"
// Default value for enchantment limits
private const val DEFAULT_ENCHANT_LIMIT = 5
// Default value for limiting repair cost
const val DEFAULT_LIMIT_REPAIR = false
// Default value for repair cost limit
const val DEFAULT_LIMIT_REPAIR_VALUE = 39
// Default value for level cost on item repair
const val DEFAULT_ITEM_REPAIR_COST = 2
// Default value for level cost per unit repair
const val DEFAULT_UNIT_REPAIR_COST = 1
// Default value for level cost on item renaming
const val DEFAULT_ITEM_RENAME_COST = 1
// Default value for level cost on illegal enchantment on sacrifice
const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1
// Valid range for repair cost limit
@JvmField
val REPAIR_LIMIT_RANGE = 1..39
// Valid range for repair cost
@JvmField
val REPAIR_COST_RANGE = 0..255
// Valid range for rename cost
@JvmField
val ITEM_RENAME_COST_RANGE = 0..255
// Valid range for illegal enchantment conflict cost
@JvmField
val SACRIFICE_ILLEGAL_COST_RANGE = 0..255
// Default for removing repair cost limits
const val DEFAULT_REMOVE_LIMIT = false
// Valid range for an enchantment limit
@JvmField
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 value for debug logging
private const val DEFAULT_VERBOSE_DEBUG_LOG = false
@ -155,6 +182,7 @@ object ConfigOptions {
.takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE }
?: DEFAULT_SACRIFICE_ILLEGAL_COST
}
/**
* Whether to remove repair cost limit
*/
@ -217,8 +245,9 @@ object ConfigOptions {
/**
* Get an array of key of basic config options
*/
fun getBasicConfigKeys(): Array<String>{
return arrayOf(DEFAULT_LIMIT_PATH,
fun getBasicConfigKeys(): Array<String> {
return arrayOf(
DEFAULT_LIMIT_PATH,
LIMIT_REPAIR_COST,
LIMIT_REPAIR_VALUE,
ITEM_REPAIR_COST,

View file

@ -34,43 +34,51 @@ object EnchantmentUtil {
if (!containsKey(enchantment)) {
// Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions
this[enchantment] = level
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment);
if(!player.hasPermission(CustomAnvil.bypassFusePermission) &&
(conflictType != ConflictType.NO_CONFLICT)){
val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
if (!player.hasPermission(CustomAnvil.bypassFusePermission) &&
(conflictType != ConflictType.NO_CONFLICT)
) {
CustomAnvil.verboseLog("Enchantment not yet in result list, but there is conflict (${enchantment.key}, conflict: $conflictType)")
this.remove(enchantment)
}
}
// Enchantment already in result list
else{
else {
// ... and they are conflicting
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment)
if((conflictType != ConflictType.NO_CONFLICT)
&& !player.hasPermission(CustomAnvil.bypassFusePermission)){
val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
if ((conflictType != ConflictType.NO_CONFLICT)
&& !player.hasPermission(CustomAnvil.bypassFusePermission)
) {
CustomAnvil.verboseLog("Enchantment already in result list, and they are conflicting (${enchantment.key}, conflict: $conflictType)")
return@forEach
}
// ... and they're not the same level
if(this[enchantment] != other[enchantment]){
if (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 }
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]!! +1
var newLevel = this[enchantment]!! + 1
// Get max level or 255 if player can bypass
val maxLevel = if(player.hasPermission(CustomAnvil.bypassLevelPermission)){
val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission)) {
255
}else{
} else {
ConfigOptions.enchantLimit(enchantment)
}
newLevel = min(newLevel, maxLevel)
if (newLevel > 0) { this[enchantment] = newLevel }
if (newLevel > 0) {
this[enchantment] = newLevel
}
}
}
}

View file

@ -75,7 +75,7 @@ object ItemUtil {
(itemMeta as? Damageable)?.let {
val durability = type.maxDurability.toInt()
val firstDamage = (first.itemMeta as? Damageable)?.damage ?: 0
if( firstDamage == 0) return false
if (firstDamage == 0) return false
val firstDurability = durability - firstDamage
val secondDamage = (second.itemMeta as? Damageable)?.damage ?: 0
@ -96,12 +96,12 @@ object ItemUtil {
(itemMeta as? Damageable)?.let {
val durability = type.maxDurability.toInt()
val firstDamage = it.damage
if( firstDamage == 0) return 0
if (firstDamage == 0) return 0
var unitCount = 0
var damage = firstDamage
while((unitCount < unitAmount) && (damage > 0)){
while ((unitCount < unitAmount) && (damage > 0)) {
unitCount++
damage = ceil(firstDamage - durability*percentPerUnit*unitCount).toInt()
damage = ceil(firstDamage - durability * percentPerUnit * unitCount).toInt()
}
it.damage = max(damage, 0)

View file

@ -11,11 +11,11 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions
class EditConfigExecutor : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if(!sender.hasPermission(CustomAnvil.editConfigPermission)) {
if (!sender.hasPermission(CustomAnvil.editConfigPermission)) {
sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM)
return false
}
if(sender !is HumanEntity) return false
if (sender !is HumanEntity) return false
MainConfigGui.INSTANCE.show(sender)
return true

View file

@ -13,18 +13,18 @@ import xyz.alexcrea.cuanvil.util.MetricsUtil
class ReloadExecutor : CommandExecutor {
override fun onCommand(sender: CommandSender, cmd: Command, cmdstr: String, args: Array<out String>): Boolean {
if(!sender.hasPermission(CustomAnvil.commandReloadPermission)) {
if (!sender.hasPermission(CustomAnvil.commandReloadPermission)) {
sender.sendMessage("§cYou do not have permission to reload the config")
return false
}
sender.sendMessage("§eReloading config...")
val hardfail = args.isNotEmpty() && ("hard".equals(args[0],true))
val hardfail = args.isNotEmpty() && ("hard".equals(args[0], true))
val commandSuccess = commandBody(hardfail)
if(commandSuccess){
if (commandSuccess) {
sender.sendMessage("§aConfig reloaded !")
}else{
} else {
sender.sendMessage("§cConfig was not able to be reloaded...")
if(hardfail){
if (hardfail) {
sender.sendMessage("§4Hard fail, plugin disabled")
}
}
@ -34,9 +34,9 @@ class ReloadExecutor : CommandExecutor {
/**
* Execute the command, return true if success or false otherwise
*/
private fun commandBody(hardfail: Boolean): Boolean{
private fun commandBody(hardfail: Boolean): Boolean {
try {
if(!ConfigHolder.reloadAllFromDisk(hardfail)) return false
if (!ConfigHolder.reloadAllFromDisk(hardfail)) return false
// Then update all global gui containing value from config
BasicConfigGui.INSTANCE.updateGuiValues()
@ -48,7 +48,7 @@ class ReloadExecutor : CommandExecutor {
MetricsUtil.testIfConfigIsDefault()
return true
}catch (e: Exception){
} catch (e: Exception) {
e.printStackTrace()
return false
}

View file

@ -4,7 +4,7 @@ import org.bukkit.Material
import java.util.*
abstract class AbstractMaterialGroup(private val name: String) {
protected val includedMaterial by lazy {createDefaultSet()}
protected val includedMaterial by lazy { createDefaultSet() }
/**
* Get the group default set
@ -14,24 +14,24 @@ abstract class AbstractMaterialGroup(private val name: String) {
/**
* Get if a material is allowed following the group policy
*/
open fun contain(mat : Material): Boolean {
open fun contain(mat: Material): Boolean {
return mat in getMaterials()
}
/**
* Get if a group is referenced by this:
*/
abstract fun isReferencing(other : AbstractMaterialGroup): Boolean
abstract fun isReferencing(other: AbstractMaterialGroup): Boolean
/**
* Push a material to this group to follow this group policy
*/
abstract fun addToPolicy(mat : Material)
abstract fun addToPolicy(mat: Material)
/**
* Push a group to this group to follow this group policy
*/
abstract fun addToPolicy(other : AbstractMaterialGroup)
abstract fun addToPolicy(other: AbstractMaterialGroup)
/**
* Get the group contained material as a set
@ -44,6 +44,7 @@ abstract class AbstractMaterialGroup(private val name: String) {
open fun getNonGroupInheritedMaterials(): EnumSet<Material> {
return includedMaterial
}
/**
* Get the group non-inherited material as a set
*/
@ -69,19 +70,19 @@ abstract class AbstractMaterialGroup(private val name: String) {
*/
abstract fun getGroups(): MutableSet<AbstractMaterialGroup>
open fun getRepresentativeMaterial() : Material {
open fun getRepresentativeMaterial(): Material {
// Test inner material
val matIterator = includedMaterial.iterator()
while(matIterator.hasNext()){
while (matIterator.hasNext()) {
val material = matIterator.next()
if(material.isAir) continue
if (material.isAir) continue
return material
}
// Test included group representative material
val groupIterator = getGroups().iterator()
while (groupIterator.hasNext()){
while (groupIterator.hasNext()) {
val groupMat = groupIterator.next().getRepresentativeMaterial()
if(groupMat.isAir) continue
if (groupMat.isAir) continue
return groupMat
}
return Material.PAPER

View file

@ -7,29 +7,30 @@ import org.bukkit.enchantments.Enchantment
class EnchantConflictGroup(
val name: String,
private val cantConflict: AbstractMaterialGroup,
val minBeforeBlock: Int){
val minBeforeBlock: Int
) {
private val enchantments = HashSet<Enchantment>()
fun addEnchantment(enchant: Enchantment){
fun addEnchantment(enchant: Enchantment) {
enchantments.add(enchant)
}
fun allowed(enchants: Set<Enchantment>, mat: Material) : Boolean{
if(enchantments.size < minBeforeBlock){
fun allowed(enchants: Set<Enchantment>, mat: Material): Boolean {
if (enchantments.size < minBeforeBlock) {
return true
}
if(cantConflict.contain(mat)){
if (cantConflict.contain(mat)) {
return true
}
// Count the amount of enchantment that are in the list
var enchantAmount = 0
for (enchantment in enchants) {
if(enchantment !in enchantments) continue
if (enchantment !in enchantments) continue
CustomAnvil.verboseLog("Enchant ${enchantment.key} is in: ${enchantAmount + 1}/$minBeforeBlock ")
if(++enchantAmount > minBeforeBlock){
if (++enchantAmount > minBeforeBlock) {
return false
}
@ -37,8 +38,8 @@ class EnchantConflictGroup(
return true
}
fun getCantConflictGroup(): AbstractMaterialGroup{
return this.cantConflict;
fun getCantConflictGroup(): AbstractMaterialGroup {
return this.cantConflict
}
fun getEnchants(): HashSet<Enchantment> {
@ -53,9 +54,9 @@ class EnchantConflictGroup(
fun getRepresentativeMaterial(): Material {
val groups = getCantConflictGroup().getGroups()
val groupIterator = groups.iterator()
while (groupIterator.hasNext()){
while (groupIterator.hasNext()) {
val mat = groupIterator.next().getRepresentativeMaterial()
if(mat != Material.ENCHANTED_BOOK) return mat
if (mat != Material.ENCHANTED_BOOK) return mat
}
return Material.ENCHANTED_BOOK

View file

@ -11,13 +11,17 @@ class EnchantConflictManager {
companion object {
// Path for the enchantments list
const val ENCH_LIST_PATH = "enchantments"
// Path for group list related to the conflict
const val CONFLICT_GROUP_PATH = "notAffectedGroups"
// Path for the maximum number of enchantment before validating the conflict
const val ENCH_MAX_PATH = "maxEnchantmentBeforeConflict"
// Path for a flag: if the enchantment will be used in the last supported version
// TODO maybe replace this system by a list of "future" enchantment.
private const val FUTURE_USE_PATH = "useInFuture"
// Default name for a joining group
private const val DEFAULT_GROUP_NAME = "joinedGroup"
}
@ -26,64 +30,64 @@ class EnchantConflictManager {
lateinit var conflictList: ArrayList<EnchantConflictGroup>
// Read and prepare all conflict
fun prepareConflicts(config: ConfigurationSection, itemManager: ItemGroupManager){
fun prepareConflicts(config: ConfigurationSection, itemManager: ItemGroupManager) {
conflictMap = HashMap()
conflictList = ArrayList()
val keys = config.getKeys(false)
for (key in keys) {
val section = config.getConfigurationSection(key)!!
val conflict = createConflict(section,itemManager,key)
if(conflict != null){
addToMap(conflict)
conflictList.add(conflict)
}
val conflict = createConflict(section, itemManager, key)
addToMap(conflict)
conflictList.add(conflict)
}
}
// Add the conflict to the map
private fun addToMap(conflict: EnchantConflictGroup){
conflict.getEnchants().forEach{ enchant ->
addConflictToConflictMap(enchant, conflict);
private fun addToMap(conflict: EnchantConflictGroup) {
conflict.getEnchants().forEach { enchant ->
addConflictToConflictMap(enchant, conflict)
}
}
fun addConflictToConflictMap(enchant: Enchantment, conflict: EnchantConflictGroup){
if(!conflictMap.containsKey(enchant)){
fun addConflictToConflictMap(enchant: Enchantment, conflict: EnchantConflictGroup) {
if (!conflictMap.containsKey(enchant)) {
conflictMap[enchant] = ArrayList()
}
conflictMap[enchant]!!.add(conflict)
}
fun removeConflictFromMap(enchant: Enchantment, conflict: EnchantConflictGroup): Boolean{
fun removeConflictFromMap(enchant: Enchantment, conflict: EnchantConflictGroup): Boolean {
return conflictMap[enchant]!!.remove(conflict)
}
// create and read a conflict from a yaml section
private fun createConflict(section: ConfigurationSection,
itemManager: ItemGroupManager,
conflictName: String): EnchantConflictGroup? {
private fun createConflict(
section: ConfigurationSection,
itemManager: ItemGroupManager,
conflictName: String
): EnchantConflictGroup {
// Is it planed for the future
val futureUse = section.getBoolean(FUTURE_USE_PATH,false)
val futureUse = section.getBoolean(FUTURE_USE_PATH, false)
// Create conflict
val conflict = createConflictObject(section,itemManager,conflictName)
val conflict = createConflictObject(section, itemManager, conflictName)
// Read and add enchantment to conflict
val enchantList = section.getStringList(ENCH_LIST_PATH)
for (enchantName in enchantList) {
val enchantKey = NamespacedKey.minecraft(enchantName)
val enchant = Enchantment.getByKey(enchantKey)
if(enchant == null){
if(!futureUse){
if (enchant == null) {
if (!futureUse) {
CustomAnvil.instance.logger.warning("Enchantment $enchantName do not exist but was asked for conflict $conflictName")
}
continue
}
conflict.addEnchantment(enchant)
}
if(conflict.getEnchants().size == 0){
if(!futureUse){
if (conflict.getEnchants().size == 0) {
if (!futureUse) {
CustomAnvil.instance.logger.warning("Conflict $conflictName do not have valid enchantment, it will not do anything")
}
}
@ -91,12 +95,14 @@ class EnchantConflictManager {
return conflict
}
private fun createConflictObject(section: ConfigurationSection,
itemManager: ItemGroupManager,
conflictName: String): EnchantConflictGroup {
private fun createConflictObject(
section: ConfigurationSection,
itemManager: ItemGroupManager,
conflictName: String
): EnchantConflictGroup {
// Get the maximum number of enchantment before validating the conflict
var minBeforeBlock = section.getInt(ENCH_MAX_PATH,0)
if(minBeforeBlock < 0){
var minBeforeBlock = section.getInt(ENCH_MAX_PATH, 0)
if (minBeforeBlock < 0) {
minBeforeBlock = 0
CustomAnvil.instance.logger.warning("Conflict $conflictName have an invalid value of $ENCH_MAX_PATH")
CustomAnvil.instance.logger.warning("It should be more or equal to 0. default to 0")
@ -112,9 +118,13 @@ class EnchantConflictManager {
return EnchantConflictGroup(conflictName, finalGroup, minBeforeBlock)
}
private fun findGroup(groupName: String, itemManager: ItemGroupManager, conflictName: String): AbstractMaterialGroup {
private fun findGroup(
groupName: String,
itemManager: ItemGroupManager,
conflictName: String
): AbstractMaterialGroup {
val group = itemManager.get(groupName)
if(group == null){
if (group == null) {
CustomAnvil.instance.logger.warning("Group $groupName do not exist but is ask by conflict $conflictName")
return IncludeGroup("error_placeholder")
}
@ -122,7 +132,7 @@ class EnchantConflictManager {
return group
}
fun isConflicting(base: Set<Enchantment>,mat: Material, newEnchant: Enchantment): ConflictType {
fun isConflicting(base: Set<Enchantment>, mat: Material, newEnchant: Enchantment): ConflictType {
CustomAnvil.verboseLog("Testing conflict for ${newEnchant.key} on ${mat.key}")
val conflictList = conflictMap[newEnchant] ?: return ConflictType.NO_CONFLICT
CustomAnvil.verboseLog("Did not get skipped")
@ -130,13 +140,13 @@ class EnchantConflictManager {
var result = ConflictType.NO_CONFLICT
for (conflict in conflictList) {
CustomAnvil.verboseLog("Is against ${conflict.name}")
val conflicting = conflict.allowed(base,mat)
val conflicting = conflict.allowed(base, mat)
CustomAnvil.verboseLog("Was against ${conflict.name} and conflicting: $conflicting ")
if(!conflicting) {
if(conflict.getEnchants().size <= 1){
if (!conflicting) {
if (conflict.getEnchants().size <= 1) {
result = ConflictType.SMALL_CONFLICT
CustomAnvil.verboseLog("Small conflict, continuing")
}else{
} else {
return ConflictType.BIG_CONFLICT
}
}
@ -146,7 +156,7 @@ class EnchantConflictManager {
}
enum class ConflictType{
enum class ConflictType {
NO_CONFLICT,
SMALL_CONFLICT,
BIG_CONFLICT

View file

@ -3,17 +3,17 @@ package xyz.alexcrea.cuanvil.group
import org.bukkit.Material
import java.util.*
class ExcludeGroup(name: String): AbstractMaterialGroup(name) {
class ExcludeGroup(name: String) : AbstractMaterialGroup(name) {
override fun createDefaultSet(): EnumSet<Material> {
return EnumSet.allOf(Material::class.java)
}
private var includedGroup: MutableSet<AbstractMaterialGroup> = HashSet()
private val groupItems by lazy {createDefaultSet()}
private val groupItems by lazy { createDefaultSet() }
override fun isReferencing(other: AbstractMaterialGroup): Boolean {
for (materialGroup in includedGroup.iterator()) {
if((materialGroup == other) || (materialGroup.isReferencing(other))){
if ((materialGroup == other) || (materialGroup.isReferencing(other))) {
return true
}
}
@ -36,7 +36,7 @@ class ExcludeGroup(name: String): AbstractMaterialGroup(name) {
includedGroup.clear()
groups.forEach { group ->
if(!group.isReferencing(this)) {
if (!group.isReferencing(this)) {
includedGroup.add(group)
groupItems.removeAll(group.getMaterials())
}

View file

@ -3,17 +3,17 @@ package xyz.alexcrea.cuanvil.group
import org.bukkit.Material
import java.util.*
class IncludeGroup(name: String): AbstractMaterialGroup(name) {
class IncludeGroup(name: String) : AbstractMaterialGroup(name) {
override fun createDefaultSet(): EnumSet<Material> {
return EnumSet.noneOf(Material::class.java)
}
private var includedGroup: MutableSet<AbstractMaterialGroup> = HashSet()
private val groupItems by lazy {createDefaultSet()}
private val groupItems by lazy { createDefaultSet() }
override fun isReferencing(other: AbstractMaterialGroup): Boolean {
for (materialGroup in includedGroup.iterator()) {
if((materialGroup == other) || (materialGroup.isReferencing(other))){
if ((materialGroup == other) || (materialGroup.isReferencing(other))) {
return true
}
}
@ -36,7 +36,7 @@ class IncludeGroup(name: String): AbstractMaterialGroup(name) {
includedGroup.clear()
groups.forEach { group ->
if(!group.isReferencing(this)){
if (!group.isReferencing(this)) {
includedGroup.add(group)
groupItems.addAll(group.getMaterials())
}

View file

@ -4,49 +4,53 @@ import io.delilaheve.CustomAnvil
import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection
import java.util.*
import kotlin.collections.LinkedHashMap
class ItemGroupManager {
companion object {
// Path for group type
private const val GROUP_TYPE_PATH = "type"
// Path for included items list
private const val MATERIAL_LIST_PATH = "items"
// Path for included groups list
private const val GROUP_LIST_PATH = "groups"
// Temporary list of elements in default config that are use in future
private val FUTURE_MATERIAL = setOf("PIGLIN_HEAD","BRUSH")
private val FUTURE_MATERIAL = setOf("PIGLIN_HEAD", "BRUSH")
}
lateinit var groupMap : LinkedHashMap<String, AbstractMaterialGroup>
lateinit var groupMap: LinkedHashMap<String, AbstractMaterialGroup>
// Read and create material groups
fun prepareGroups(config: ConfigurationSection){
fun prepareGroups(config: ConfigurationSection) {
groupMap = LinkedHashMap()
val keys = config.getKeys(false)
for (key in keys) {
if(groupMap.containsKey(key))
if (groupMap.containsKey(key))
continue
createGroup(config, keys, key)
}
}
// Create group by key
private fun createGroup(config: ConfigurationSection,
keys: Set<String>,
key: String): AbstractMaterialGroup {
private fun createGroup(
config: ConfigurationSection,
keys: Set<String>,
key: String
): AbstractMaterialGroup {
val groupSection = config.getConfigurationSection(key)!!
val groupType = groupSection.getString(GROUP_TYPE_PATH,null)
val groupType = groupSection.getString(GROUP_TYPE_PATH, null)
// Create Material group according to the group type
val group: AbstractMaterialGroup
if(GroupType.EXCLUDE.equal(groupType)){
if (GroupType.EXCLUDE.equal(groupType)) {
group = ExcludeGroup(key)
}else {
} else {
group = IncludeGroup(key)
if(!GroupType.INCLUDE.equal(groupType)){
if (!GroupType.INCLUDE.equal(groupType)) {
CustomAnvil.instance.logger.warning("Group $key have an invalid group type. default to Include.")
}
}
@ -57,20 +61,23 @@ class ItemGroupManager {
}
// Read Group elements
private fun readGroup(group: AbstractMaterialGroup,
groupSection: ConfigurationSection,
config: ConfigurationSection,
keys: Set<String>){
private fun readGroup(
group: AbstractMaterialGroup,
groupSection: ConfigurationSection,
config: ConfigurationSection,
keys: Set<String>
) {
// Read material to include in this group policy
val materialList = groupSection.getStringList(MATERIAL_LIST_PATH)
for (materialTemp in materialList) {
val materialName = materialTemp.uppercase(Locale.getDefault())
val material = Material.getMaterial(materialName)
if(material == null){
if (material == null) {
// Check if we should warn the user
if(materialName !in FUTURE_MATERIAL){
if (materialName !in FUTURE_MATERIAL) {
CustomAnvil.instance.logger.warning(
"Unknown material $materialTemp on group ${group.getName()}")
"Unknown material $materialTemp on group ${group.getName()}"
)
}
continue
@ -82,23 +89,26 @@ class ItemGroupManager {
// please note the group name is case-sensitive.
val groupList = groupSection.getStringList(GROUP_LIST_PATH)
for (groupName in groupList) {
if(groupName !in keys){
if (groupName !in keys) {
CustomAnvil.instance.logger.warning(
"Group $groupName do not exist but is included in group ${group.getName()}")
"Group $groupName do not exist but is included in group ${group.getName()}"
)
continue
}
// Get other group or create it if not yet created
val otherGroup = if(!groupMap.containsKey(groupName)){
createGroup(config,keys,groupName)
}else{
val otherGroup = if (!groupMap.containsKey(groupName)) {
createGroup(config, keys, groupName)
} else {
groupMap[groupName]!!
}
// Avoid self reference or it will create an infinite loop
if(otherGroup.isReferencing(group)){
if (otherGroup.isReferencing(group)) {
CustomAnvil.instance.logger.warning(
"Group $groupName is on a reference loop with group ${group.getName()} !")
"Group $groupName is on a reference loop with group ${group.getName()} !"
)
CustomAnvil.instance.logger.warning(
"Please fix it in your item_groups config or the plugin will probably not work as expected.")
"Please fix it in your item_groups config or the plugin will probably not work as expected."
)
continue
}
@ -121,10 +131,10 @@ enum class GroupType(private val groupID: String) {
;
// Test if string is equal to the groupID of this enum
fun equal(toTest: String?): Boolean{
if(toTest == null)
fun equal(toTest: String?): Boolean {
if (toTest == null)
return false
return groupID.contentEquals(toTest.lowercase(Locale.getDefault()))
return groupID.contentEquals(toTest.lowercase(Locale.getDefault()))
}
}

View file

@ -11,7 +11,7 @@ import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.function.Consumer
class ChatEventListener : Listener{
class ChatEventListener : Listener {
private val playerListenMap: ConcurrentHashMap<UUID, Consumer<String?>> = ConcurrentHashMap()

View file

@ -31,12 +31,11 @@ object MetricsUtil {
*/
private fun getHashFromKey(section: ConfigurationSection, key: String): Int {
// Key is assumend to exist
val resultHash: Int
if(section.isConfigurationSection(key)){
val resultHash = if (section.isConfigurationSection(key)) {
val sectionResult = getConfigurationHash(section.getConfigurationSection(key)!!)
resultHash = key.hashCode() xor sectionResult
}else{
resultHash = key.hashCode() xor section.getString(key).hashCode()
key.hashCode() xor sectionResult
} else {
key.hashCode() xor section.getString(key).hashCode()
}
return resultHash.hashCode()
}
@ -47,7 +46,7 @@ object MetricsUtil {
private fun getConfigurationHash(section: ConfigurationSection): Int {
var resultHash = 0
for (key in section.getKeys(false)) {
resultHash = resultHash xor getHashFromKey(section,key)
resultHash = resultHash xor getHashFromKey(section, key)
}
return resultHash
}
@ -55,10 +54,10 @@ object MetricsUtil {
/**
* Get hash value of the default config
*/
private fun testBaseConfig(defaultConfig: ConfigurationSection): Int{
private fun testBaseConfig(defaultConfig: ConfigurationSection): Int {
var result = 0
for (key in ConfigOptions.getBasicConfigKeys()) {
result = result xor getHashFromKey(defaultConfig,key)
result = result xor getHashFromKey(defaultConfig, key)
}
return result
}
@ -66,7 +65,7 @@ object MetricsUtil {
/**
* Test if the used configuration is the default config
*/
fun testIfConfigIsDefault(){
fun testIfConfigIsDefault() {
// Calculate hash of config
val baseConfig = testBaseConfig(ConfigHolder.DEFAULT_CONFIG.config)
val limitEnchantConfig = getHashFromKey(ConfigHolder.DEFAULT_CONFIG.config, ConfigOptions.ENCHANT_LIMIT_ROOT)
@ -77,37 +76,49 @@ object MetricsUtil {
// Test if default
isDefaultBaseConfig = baseConfigHash == baseConfig
isDefaultEnchantLimitsConfig = enchantLimitsConfigHash == limitEnchantConfig
isDefaultEnchantValuesConfig = enchantValuesConfigHash == enchantValueConfig
isDefaultEnchantValuesConfig = enchantValuesConfigHash == enchantValueConfig
isDefaultEnchantConflictConfig = enchantConflictConfigHash == enchantConflictConfig
isDefaultItemGroupsConfig = itemGroupsConfigHash == itemGroupConfig
isDefaultUnitRepairItemConfig = unitRepairItemConfigHash == unitRepairConfig
// If not default and debug flag active, print the hash.
if(ConfigOptions.debugLog){
if(!isDefaultBaseConfig){CustomAnvil.log("baseConfig: $baseConfig")}
if(!isDefaultEnchantLimitsConfig){CustomAnvil.log("limitEnchantConfig: $limitEnchantConfig")}
if(!isDefaultEnchantValuesConfig){CustomAnvil.log("enchantValueConfig: $enchantValueConfig")}
if(!isDefaultEnchantConflictConfig){CustomAnvil.log("enchantConflictConfig: $enchantConflictConfig")}
if(!isDefaultItemGroupsConfig){CustomAnvil.log("itemGroupConfig: $itemGroupConfig")}
if(!isDefaultUnitRepairItemConfig){CustomAnvil.log("unitRepairConfig: $unitRepairConfig")}
if (ConfigOptions.debugLog) {
if (!isDefaultBaseConfig) {
CustomAnvil.log("baseConfig: $baseConfig")
}
if (!isDefaultEnchantLimitsConfig) {
CustomAnvil.log("limitEnchantConfig: $limitEnchantConfig")
}
if (!isDefaultEnchantValuesConfig) {
CustomAnvil.log("enchantValueConfig: $enchantValueConfig")
}
if (!isDefaultEnchantConflictConfig) {
CustomAnvil.log("enchantConflictConfig: $enchantConflictConfig")
}
if (!isDefaultItemGroupsConfig) {
CustomAnvil.log("itemGroupConfig: $itemGroupConfig")
}
if (!isDefaultUnitRepairItemConfig) {
CustomAnvil.log("unitRepairConfig: $unitRepairConfig")
}
}
}
fun notifyChange(holder: ConfigHolder, path: String){
if(ConfigHolder.DEFAULT_CONFIG.equals(holder)){
if(path.startsWith(ConfigOptions.ENCHANT_LIMIT_ROOT+".")){
isDefaultEnchantLimitsConfig = false;
}else if(path.startsWith(ConfigOptions.ENCHANT_VALUES_ROOT+".")){
isDefaultEnchantValuesConfig = false;
}else{
isDefaultBaseConfig = false;
fun notifyChange(holder: ConfigHolder, path: String) {
if (ConfigHolder.DEFAULT_CONFIG.equals(holder)) {
if (path.startsWith(ConfigOptions.ENCHANT_LIMIT_ROOT + ".")) {
isDefaultEnchantLimitsConfig = false
} else if (path.startsWith(ConfigOptions.ENCHANT_VALUES_ROOT + ".")) {
isDefaultEnchantValuesConfig = false
} else {
isDefaultBaseConfig = false
}
}else if(ConfigHolder.CONFLICT_HOLDER.equals(holder)){
isDefaultEnchantConflictConfig = false;
}else if(ConfigHolder.ITEM_GROUP_HOLDER.equals(holder)){
isDefaultItemGroupsConfig = false;
}else if(ConfigHolder.UNIT_REPAIR_HOLDER.equals(holder)){
isDefaultUnitRepairItemConfig = false;
} else if (ConfigHolder.CONFLICT_HOLDER.equals(holder)) {
isDefaultEnchantConflictConfig = false
} else if (ConfigHolder.ITEM_GROUP_HOLDER.equals(holder)) {
isDefaultItemGroupsConfig = false
} else if (ConfigHolder.UNIT_REPAIR_HOLDER.equals(holder)) {
isDefaultUnitRepairItemConfig = false
}
}

View file

@ -8,6 +8,7 @@ object UnitRepairUtil {
// Default value for user set default unit repair %
private const val DEFAULT_DEFAULT_UNIT_REPAIR = 0.25
// Path to user default unit repair value
private const val UNIT_REPAIR_DEFAULT_PATH = "default_repair_amount"
@ -18,23 +19,23 @@ object UnitRepairUtil {
fun ItemStack.getRepair(
other: ItemStack?
): Double? {
if(other == null) return null
if (other == null) return null
val config = ConfigHolder.UNIT_REPAIR_HOLDER.config
// Get configuration section if exist
val otherName = other.type.name.uppercase()
var section = config.getConfigurationSection(otherName)
if(section == null){
if (section == null) {
section = config.getConfigurationSection(otherName.lowercase())
if(section == null) return null
if (section == null) return null
}
// Get repair amount
var userDefault = config.getDouble(UNIT_REPAIR_DEFAULT_PATH, DEFAULT_DEFAULT_UNIT_REPAIR)
if(userDefault <= 0){
if (userDefault <= 0) {
userDefault = DEFAULT_DEFAULT_UNIT_REPAIR
}
return getRepairAmount(this,section,userDefault)
return getRepairAmount(this, section, userDefault)
}
/**
@ -42,16 +43,16 @@ object UnitRepairUtil {
* 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?{
private fun getRepairAmount(item: ItemStack, section: ConfigurationSection, default: Double): Double? {
val itemName = item.type.name.uppercase()
val repairValue = if(section.isDouble(itemName)){
val repairValue = if (section.isDouble(itemName)) {
section.getDouble(itemName)
}else if(section.isDouble(itemName.lowercase())){
} else if (section.isDouble(itemName.lowercase())) {
section.getDouble(itemName.lowercase())
}else{
} else {
return null
}
if(repairValue <= 0)
if (repairValue <= 0)
return default
return repairValue
}