diff --git a/README.md b/README.md index 5cde745..77c6618 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ or [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest) - Display xp cost instead of "to expensive" when above lv 40. (need ProtocoLib) - Can handle some custom enchantment plugins (see bellow for more information) - Gui to configure the plugin in game. +- Support of color code and hexadecimal color --- ### Permissions: ```yml @@ -34,6 +35,9 @@ ca.bypass.fuse: Allow player to combine every enchantments to every item (no cus ca.bypass.level: Allow player to bypass every level limit (no custom limit) ca.command.reload: Allow administrator to reload the plugin's configs ca.config.edit: Allow administrator to edit the plugin's config in game +# Related to use of color (usage of permission for color is toggleable in basic config gui or config.yml) +ca.color.code: Allow player to use color code if permission is required (toggleable) +ca.color.hex: Allow player to use hexadecimal color if permission is required (toggleable) ``` /!\ version under 1.3.1 use other permission. from 1.2.0 to 1.3.1-A1 use ua.unsafe instead of ca.affected under 1.2.0 replace ca prefix by ue and use ue.unsafe. some permission/features may not exist before the last version. diff --git a/build.gradle.kts b/build.gradle.kts index 31aad8f..1c816c7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.5.3" +version = "1.5.4-beta.1" java { disableAutoTargetJvm() diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java index 4d900dc..8729232 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java @@ -59,8 +59,8 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { private void init() { Pattern pattern = new Pattern( GuiSharedConstant.EMPTY_GUI_FULL_LINE, - "0L0T0I0S0", - "0C0R0U0r0", + "LT0I0S0cp", + "CR0U0r0hP", "B00000000" ); pane = new PatternPane(0, 0, 9, 4, pattern); @@ -73,9 +73,9 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { updateGuiValues(); } - private BoolSettingsGui.BoolSettingFactory capAnvilCostFactory; // L character + private BoolSettingsGui.BoolSettingFactory capAnvilCost; // L character private GuiItem noCapRepairItem; - private IntSettingsGui.IntSettingFactory maxAnvilCostFactory; // C character + private IntSettingsGui.IntSettingFactory maxAnvilCost; // C character private GuiItem noMaxCostItem; private BoolSettingsGui.BoolSettingFactory removeAnvilCostLimit; // R character @@ -86,12 +86,20 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { private IntSettingsGui.IntSettingFactory itemRenameCost; // r character private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost; // S character + private BoolSettingsGui.BoolSettingFactory allowColorCode; // c character + private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character + + private BoolSettingsGui.BoolSettingFactory permissionNeededForColor; // p character + private GuiItem noPermissionNeededItem; + private IntSettingsGui.IntSettingFactory useOfColorCost; // P character + private GuiItem noColorCostItem; + /** * Prepare basic gui displayed items factory and static items.. */ protected void prepareValues() { // cap anvil cost - this.capAnvilCostFactory = BoolSettingsGui.boolFactory("\u00A78Cap Anvil Cost ?", this, + this.capAnvilCost = BoolSettingsGui.boolFactory("\u00A78Cap Anvil Cost ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, "\u00A77All anvil cost will be capped to \u00A7aMax Anvil Cost\u00A77 if enabled.", @@ -110,7 +118,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // repair cost item IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; - this.maxAnvilCostFactory = IntSettingsGui.intFactory("\u00A78Max Anvil Cost", this, + this.maxAnvilCost = IntSettingsGui.intFactory("\u00A78Max Anvil Cost", this, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "\u00A77Max cost the Anvil can get to.", @@ -147,6 +155,10 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, getReplaceToExpensiveLore()); + // ------------ + // Cost config + // ------------ + // item repair cost range = ConfigOptions.REPAIR_COST_RANGE; this.itemRepairCost = IntSettingsGui.intFactory("\u00A78Item Repair Cost", this, @@ -194,6 +206,70 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, 1, 5, 10, 50, 100); + // ------------- + // Color config + // ------------- + + // Allow us of color code + this.allowColorCode = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Color Code ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, + "\u00A77Whether players can use color code.", + "\u00A77Color code a formatted like \u00A7a&a\u00A77 and is used in the rename field of the anvil.", + "\u00A77Player may need permission to use color code if \u00A7ePlayer need permission to use color\u00A77 is enabled."); + + // Allow us of hexadecimal color + this.allowHexColor = BoolSettingsGui.boolFactory("\u00A78Allow Use Of Hexadecimal Color ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, + "\u00A77Whether players can use hexadecimal color.", + "\u00A77Color code a formatted like \u00A72#012345 \u00A77and is used in the rename field of the anvil.", + "\u00A77Player may need permission to use color code if \u00A7ePermission Needed For Color\u00A77 is enabled."); + + // Permission needed for color + this.permissionNeededForColor = BoolSettingsGui.boolFactory("\u00A78Need Permission To Use Color ?", this, + ConfigHolder.DEFAULT_CONFIG, + ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, + "\u00A77Whether players should have permission to be able to use colors.", + "\u00A77Give player \u00A7eca.color.code\u00A77 Permission to allow use of color code.", + "\u00A77Give player \u00A7eca.color.hex\u00A77 Permission to allow use of hexadecimal color."); + + // Permission needed for color not necessary + item = new ItemStack(Material.BARRIER); + meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7cNeed Permission To Use Color ?"); + meta.setLore(Arrays.asList("\u00A77This config can do something only if one of the following config is enabled:", + "\u00A77- \u00A7aAllow Use Of Color Code", + "\u00A77- \u00A7aAllow Use Of Hexadecimal Color")); + item.setItemMeta(meta); + this.noPermissionNeededItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + + // Cost of using color + range = ConfigOptions.USE_OF_COLOR_COST_RANGE; + this.useOfColorCost = IntSettingsGui.intFactory("\u00A78Cost Of Using Color", this, + ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP level cost when using color code or hexadecimal color using the anvil.", + "\u00A77conflict With one of the left item enchantment" + ), + range.getFirst(), range.getLast(), + ConfigOptions.DEFAULT_USE_OF_COLOR_COST, + 1, 5, 10, 50, 100); + + // Permission needed for color not necessary + item = new ItemStack(Material.BARRIER); + meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7cCost Of Using Color"); + meta.setLore(Arrays.asList("\u00A77This config can do something only if one of the following config is enabled:", + "\u00A77- \u00A7aAllow Use Of Color Code", + "\u00A77- \u00A7aAllow Use Of Hexadecimal Color")); + item.setItemMeta(meta); + this.noColorCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + } @NotNull @@ -219,8 +295,8 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { GuiItem capAnvilCostItem; GuiItem maxAnvilCostItem; if (!this.removeAnvilCostLimit.getConfiguredValue()) { - capAnvilCostItem = this.capAnvilCostFactory.getItem("Cap Anvil Cost"); - maxAnvilCostItem = this.maxAnvilCostFactory.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); + capAnvilCostItem = this.capAnvilCost.getItem("Cap Anvil Cost"); + maxAnvilCostItem = this.maxAnvilCost.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost"); } else { capAnvilCostItem = this.noCapRepairItem; maxAnvilCostItem = this.noMaxCostItem; @@ -247,13 +323,36 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { pane.bindItem('U', unitRepairCostItem); // item rename cost - GuiItem itemRenameCost = this.itemRenameCost.getItem(Material.NAME_TAG); - pane.bindItem('r', itemRenameCost); + GuiItem itemRenameCostItem = this.itemRenameCost.getItem(Material.NAME_TAG); + pane.bindItem('r', itemRenameCostItem); // sacrifice illegal enchant cost GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK); pane.bindItem('S', illegalCostItem); + // allow color code + GuiItem allowColorCodeItem = this.allowColorCode.getItem(); + pane.bindItem('c', allowColorCodeItem); + + // allow hex color + GuiItem allowHexColorItem = this.allowHexColor.getItem(); + pane.bindItem('h', allowHexColorItem); + + // True if player could place color + if(ConfigOptions.INSTANCE.getRenameColorPossible()){ + // use permission for color + GuiItem permissionNeededItem = this.permissionNeededForColor.getItem(); + pane.bindItem('p', permissionNeededItem); + + // using color cost + GuiItem useColorCostItem = this.useOfColorCost.getItem(Material.EXPERIENCE_BOTTLE, "Use color"); + pane.bindItem('P', useColorCostItem); + }else{ + pane.bindItem('p', this.noPermissionNeededItem); + pane.bindItem('P', this.noColorCostItem); + } + + update(); } diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index 5837e98..7c6ca2a 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -12,6 +12,7 @@ import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.ChatColor import org.bukkit.GameMode import org.bukkit.Material +import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler @@ -30,8 +31,11 @@ import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair +import java.util.regex.Matcher +import java.util.regex.Pattern import kotlin.math.min + /** * Listener for anvil events */ @@ -79,7 +83,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { // Test rename lonely item if (second == null) { val resultItem = first.clone() - var anvilCost = handleRename(resultItem, inventory) + var anvilCost = handleRename(resultItem, inventory, player) // Test/stop if nothing changed. if (first == resultItem) { @@ -121,7 +125,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { // As calculatePenalty edit result, we need to calculate penalty after checking equality anvilCost += calculatePenalty(first, second, resultItem) // Calculate rename cost - anvilCost += handleRename(resultItem, inventory) + anvilCost += handleRename(resultItem, inventory, player) // Finally, we set result event.result = resultItem @@ -134,7 +138,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { val unitRepairAmount = first.getRepair(second) if (unitRepairAmount != null) { val resultItem = first.clone() - var anvilCost = handleRename(resultItem, inventory) + var anvilCost = handleRename(resultItem, inventory, player) val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount) if (repairAmount > 0) { @@ -159,20 +163,117 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { } - private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int { + private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int { // Rename item and add renaming cost resultItem.itemMeta?.let { val displayName = ChatColor.stripColor(it.displayName) - val inventoryName = ChatColor.stripColor(inventory.renameText) - if (!displayName.contentEquals(inventoryName)) { - it.setDisplayName(inventory.renameText) - resultItem.itemMeta = it - return ConfigOptions.itemRenameCost + var inventoryName = ChatColor.stripColor(inventory.renameText) + + var sumCost = 0 + + var useColor = false + if(ConfigOptions.renameColorPossible){ + val resultString = StringBuilder(inventoryName) + + useColor = handleRenamingColor(resultString, player) + + if(useColor) { + inventoryName = resultString.toString() + + sumCost+= ConfigOptions.useOfColorCost + } } + + if ((!useColor && (!displayName.contentEquals(inventoryName))) || (useColor && !(it.displayName).contentEquals(inventoryName))) { + it.setDisplayName(inventoryName) + resultItem.itemMeta = it + + sumCost+= ConfigOptions.itemRenameCost + } + + return sumCost } return 0 } + private fun handleRenamingColor(textToColor: StringBuilder, player: HumanEntity): Boolean { + val usePermission = ConfigOptions.permissionNeededForColor + val canUseColorCode = ConfigOptions.allowColorCode && (!usePermission || player.hasPermission("ca.color.code")) + val canUseHexColor = ConfigOptions.allowHexadecimalColor && (!usePermission || player.hasPermission("ca.color.hex")) + + if((!canUseColorCode) && (!canUseHexColor)) return false + + var useColor = false + // Handle color code + if(canUseColorCode){ + var nbReplacement = replaceAll(textToColor, "&", "§", 2) + nbReplacement -= 2 * replaceAll(textToColor, "§§", "&", 2) + + if(nbReplacement > 0) useColor = true + } + + if(canUseHexColor){ + val nbReplacement = replaceHexToColor(textToColor, 7) + + if(nbReplacement > 0) useColor = true + } + + return useColor + } + + /** + * Replace every instance of "from" to "to". + * @param builder The builder to replace the string from. + * @param from The source that should be replaced. + * @param to The string that should replace. + * @param endOffset Amount of character that should be ignored at the end. + * @return The number of replacement was that was done. + */ + private fun replaceAll(builder: java.lang.StringBuilder, from: String, to: String, endOffset: Int): Int { + var index = builder.indexOf(from) + var numberOfChanges = 0 + + while (index != -1 && index < builder.length - endOffset) { + builder.replace(index, index + from.length, to) + index += to.length + index = builder.indexOf(from, index) + + numberOfChanges+=1 + } + + return numberOfChanges + } + + val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string + /** + * Replace every hex color formatted like #000000 to the minecraft format + * @param builder The builder to replace the hex color from. + * @param endOffset Amount of character that should be ignored at the end. + * @return The number of replacement was that was done. + */ + private fun replaceHexToColor(builder: StringBuilder, endOffset: Int): Int { + val matcher: Matcher = HEX_PATTERN.matcher(builder) + + var numberOfChanges = 0 + var startIndex = 0 + + while(matcher.find(startIndex)){ + startIndex = matcher.start() + if(startIndex >= builder.length - endOffset) break + + builder.replace(startIndex, startIndex + 1, "§x") + startIndex+=2 + for (i in 0..5) { + builder.insert(startIndex, '§') + startIndex+=2 + } + + numberOfChanges+=1 + } + + return numberOfChanges + } + /** * Event handler logic for when a player is trying to pull an item out of the anvil */ @@ -322,8 +423,14 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { leftItem.itemMeta?.let { leftMeta -> val leftName = leftMeta.displayName output.itemMeta?.let { + // Rename cost if (!leftName.contentEquals(it.displayName)) { repairCost += ConfigOptions.itemRenameCost + + // Color cost + if(it.displayName.contains('§')){ + repairCost += ConfigOptions.useOfColorCost + } } } } @@ -396,7 +503,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { /** * Function to calculate work penalty of anvil work - * Also change result work penalty + * Also change result work penalty if right item is not null */ private fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack): Int { // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation @@ -409,10 +516,13 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener { (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 - result.itemMeta = it + // Try to set work penalty for the result item only if right item not null + if(right != null){ + result.itemMeta?.let { + (it as? Repairable)?.repairCost = leftPenalty * 2 + 1 + result.itemMeta = it + + } } CustomAnvil.log( diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 03eedcf..80dea06 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -10,87 +10,74 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantment */ object ConfigOptions { - // Path for limiting anvil cost + // ---------------------- + // Path for config values + // ---------------------- + const val CAP_ANVIL_COST = "limit_repair_cost" - - // Path for max anvil cost value const val MAX_ANVIL_COST = "limit_repair_value" - - // Path for removing anvil cost limits const val REMOVE_ANVIL_COST_LIMIT = "remove_repair_limit" - // Path for removing too expensive when unused const val REPLACE_TOO_EXPENSIVE = "replace_too_expensive" - // 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 default enchantment limits + // Color related config + const val ALLOW_COLOR_CODE = "allow_color_code" + const val ALLOW_HEXADECIMAL_COLOR = "allow_hexadecimal_color" + const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color" + const val USE_OF_COLOR_COST = "use_of_color_cost" + private const val DEFAULT_LIMIT_PATH = "default_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 + // Debug flag private const val DEBUG_LOGGING = "debug_log" - - // Debug verbose logging toggle path private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose" + // ---------------------- + // Default config values + // ---------------------- - // Default value for limiting repair cost const val DEFAULT_CAP_ANVIL_COST = false - - // Default value for repair cost limit const val DEFAULT_MAX_ANVIL_COST = 39 - - // Default for removing repair cost limits const val DEFAULT_REMOVE_ANVIL_COST_LIMIT = false - // Default for removing repair cost limits const val DEFAULT_REPLACE_TOO_EXPENSIVE = false - // 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 + // Color related config + const val DEFAULT_ALLOW_COLOR_CODE = false + const val DEFAULT_ALLOW_HEXADECIMAL_COLOR = false + const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true + const val DEFAULT_USE_OF_COLOR_COST = 0 - // Default value for enchantment limits private const val DEFAULT_ENCHANT_LIMIT = 5 - // Default value for debug logging + // Debug flag private const val DEFAULT_DEBUG_LOG = false - - // Default value for debug logging private const val DEFAULT_VERBOSE_DEBUG_LOG = false + // ------------- + // Config Ranges + // ------------- // Valid range for repair cost limit @JvmField @@ -108,6 +95,10 @@ object ConfigOptions { @JvmField val SACRIFICE_ILLEGAL_COST_RANGE = 0..1000 + // Valid range for color use cost + @JvmField + val USE_OF_COLOR_COST_RANGE = 0..1000 + // Valid range for an enchantment limit @JvmField val ENCHANT_LIMIT_RANGE = 1..255 @@ -116,6 +107,10 @@ object ConfigOptions { // Default value for an enchantment multiplier private const val DEFAULT_ENCHANT_VALUE = 0 + // ------------- + // Get methods + // ------------- + /** * Whether to cap anvil costs */ @@ -206,6 +201,53 @@ object ConfigOptions { ?: DEFAULT_SACRIFICE_ILLEGAL_COST } + /** + * Allow usage of color code + */ + val allowColorCode: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE) + } + + /** + * Allow usage of hexadecimal color + */ + val allowHexadecimalColor: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR) + } + + /** + * If one of the color component is enabled + */ + val renameColorPossible: Boolean get() { return allowColorCode || allowHexadecimalColor } + + /** + * If players need a permission to use color + */ + val permissionNeededForColor: Boolean + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getBoolean(PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR) + } + + /** + * How many xp should use of color should cost + */ + val useOfColorCost: Int + get() { + return ConfigHolder.DEFAULT_CONFIG + .config + .getInt(USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST) + .takeIf { it in USE_OF_COLOR_COST_RANGE } + ?: DEFAULT_USE_OF_COLOR_COST + } + /** * Default enchantment limit */ diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5cc0929..10da46c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -55,7 +55,24 @@ unit_repair_cost: 1 # Valid values include 0 to 1000 sacrifice_illegal_enchant_cost: 1 -# Default limit to apply to any enchants missing from override_limits +# Allow using color code and hexadecimal color. +# +# Color code are prefixed by "&" and hexadecimal color by "#". +# Color code will not be applied if it colors nothing. "&&" can be used to write "&". +allow_color_code: false +allow_hexadecimal_color: false + +# Toggle if color should only be applicable if the player a certain permission. +# +# permission are "ca.color.code" for use of color code and "ca.color.hex" for use of hexadecimal color. +permission_needed_for_color: true + +# Xp cost if the player use color in the items name on rename. +# +# Valid values include 0 to 1000. +use_of_color_cost: 0 + +# Default limit to apply to any enchants missing from enchant_limits # # Valid values include 1 to 1000 default_limit: 5 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c5ff2e5..f28e52d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -39,6 +39,14 @@ permissions: ca.config.edit: default: op description: Allow administrator to edit the plugin's config in game + # color permissions + ca.color.code: + default: op + description: Allow player to use color code if permission is required (toggleable) + ca.color.hex: + default: op + description: Allow player to use hexadecimal color if permission is required (toggleable) + # soft depend on old name, so I can disable it if it is on the same server # as it is the old name for this plugin