diff --git a/README.md b/README.md index c5954df..d7d77ea 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ or here [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest) - Can handle some custom enchantment plugins (see below for more information) - Gui to configure the plugin in game. - Support of color code and hexadecimal color +- (Experimental) folia support (gui do not work) --- ### Permissions: ```yml @@ -59,7 +60,7 @@ Use EcoEnchant restriction system by default. Here is a list of supported anvil mechanic plugins with support status: - [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) -Officially supported by Custom Anvil but still experimental. Mostly use Custom Anvil XP settings. +Officially supported by Custom Anvil but still experimental. Mostly use Custom Anvil basic XP settings. (version >= 5.4.0) If you like Custom Anvil to support a specific plugin (custom enchant or anvil mechanic). You can ask, but please note implementing compatibility will be considered @@ -88,10 +89,10 @@ For 1.21 to 1.21.1 use the [1.21 configurations](https://github.com/alexcrea/Cus Custom anvil [use bstat](https://bstats.org/plugin/bukkit/Unsafe%20Enchants%20Plus/20923) for metric. You can [disable it](https://bstats.org/getting-started) if you like. ### Planned: -- Semi manual config update on plugin or minecraft update -- Get restriction and multiplier on unknown enchantments +- Better folia support (make gui work. fix some dirty handled parts) +- Get restriction on unknown enchantments - Warn admin on unsupported minecraft version -- More features for custom anvil craft​ +- More features for custom anvil craft ### Known issue: Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta. diff --git a/build.gradle.kts b/build.gradle.kts index a2fafdb..d8ed4d9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.6.0" +version = "1.6.1" repositories { // EcoEnchants @@ -37,7 +37,7 @@ dependencies { compileOnly("com.willfp:eco:6.70.1") // Disenchantment - compileOnly("cz.kominekjan:Disenchantment:v5.3.1") + compileOnly("cz.kominekjan:Disenchantment:v5.4.0") // Include nms implementation(project(":nms:nms-common")) diff --git a/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/TaskScheduler.kt b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/TaskScheduler.kt new file mode 100644 index 0000000..e6a70dd --- /dev/null +++ b/nms/nms-common/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/TaskScheduler.kt @@ -0,0 +1,18 @@ +package xyz.alexcrea.cuanvil.dependency.scheduler + +import org.bukkit.entity.Entity +import org.bukkit.plugin.Plugin + +interface TaskScheduler { + + fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? + fun scheduleGlobally(plugin: Plugin, task: Runnable): Any?{ + return scheduleGlobally(plugin, task, 0L) + } + + fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? + fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable): Any?{ + return scheduleOnEntity(plugin, entity, task, 0L) + } + +} \ No newline at end of file diff --git a/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt b/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt new file mode 100644 index 0000000..a9bd79f --- /dev/null +++ b/nms/v1_20R3/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/FoliaScheduler.kt @@ -0,0 +1,40 @@ +package xyz.alexcrea.cuanvil.dependency.scheduler + +import io.papermc.paper.threadedregions.scheduler.ScheduledTask +import org.bukkit.Bukkit +import org.bukkit.entity.Entity +import org.bukkit.plugin.Plugin +import java.util.function.Consumer + +class FoliaScheduler : TaskScheduler { + override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? { + if(time < 1){ + return Bukkit.getGlobalRegionScheduler().run( + plugin + ) { scheduledTask: ScheduledTask? -> task.run() } + } + return Bukkit.getGlobalRegionScheduler().runDelayed( + plugin, + { scheduledTask: ScheduledTask? -> task.run() }, + time + ) + } + + + override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? { + if(time < 1){ + return entity.scheduler.run( + plugin, + { scheduledTask: ScheduledTask? -> task.run() }, + {} + ) + } + return entity.scheduler.runDelayed( + plugin, + { scheduledTask: ScheduledTask? -> task.run() }, + {}, + time + ) + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java index db577a1..ad01827 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java @@ -1,11 +1,11 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; -import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; @@ -21,8 +21,8 @@ public class ConflictAPI { private ConflictAPI() {} - private static int saveChangeTask = -1; - private static int reloadChangeTask = -1; + private static Object saveChangeTask = null; + private static Object reloadChangeTask = null; /** * Write and add a conflict. @@ -151,27 +151,27 @@ public class ConflictAPI { * Prepare a task to save conflict configuration. */ private static void prepareSaveTask() { - if(saveChangeTask != -1) return; + if(saveChangeTask != null) return; - saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.CONFLICT_HOLDER.saveToDisk(true); - saveChangeTask = -1; - }, 0L); + saveChangeTask = null; + }); } /** * Prepare a task to reload every conflict. */ private static void prepareUpdateTask() { - if(reloadChangeTask != -1) return; + if(reloadChangeTask != null) return; - reloadChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + reloadChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.CONFLICT_HOLDER.reload(); EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance(); if(conflictGui != null) conflictGui.reloadValues(); - reloadChangeTask = -1; - }, 0L); + reloadChangeTask = null; + }); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java index 250e854..32db73b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApi.java @@ -1,10 +1,10 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; -import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; @@ -19,7 +19,7 @@ public class CustomAnvilRecipeApi { private CustomAnvilRecipeApi(){} - private static int saveChangeTask = -1; + private static Object saveChangeTask = null; /** * Write and add a custom anvil recipe. @@ -103,12 +103,12 @@ public class CustomAnvilRecipeApi { * Prepare a task to save custom recipe configuration. */ private static void prepareSaveTask() { - if(saveChangeTask != -1) return; + if(saveChangeTask != null) return; - saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.CONFLICT_HOLDER.saveToDisk(true); - saveChangeTask = -1; - }, 0L); + saveChangeTask = null; + }); } /** diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java index d2244ad..01c5ed8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/EnchantmentApi.java @@ -1,13 +1,13 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; -import org.bukkit.Bukkit; import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; @@ -26,7 +26,7 @@ import java.util.Map; @SuppressWarnings("unused") public class EnchantmentApi { - private static int saveChangeTask = -1; + private static Object saveChangeTask = null; private EnchantmentApi() {} @@ -180,12 +180,12 @@ public class EnchantmentApi { * Prepare a task to save custom recipe configuration. */ private static void prepareSaveTask() { - if(saveChangeTask != -1) return; + if(saveChangeTask != null) return; - saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); - saveChangeTask = -1; - }, 0L); + saveChangeTask = null; + }); } /** diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java index 6e50ff9..dd34eb6 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/MaterialGroupApi.java @@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; import io.delilaheve.util.ConfigOptions; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; import xyz.alexcrea.cuanvil.group.ExcludeGroup; import xyz.alexcrea.cuanvil.group.IncludeGroup; @@ -24,8 +24,8 @@ public class MaterialGroupApi { private MaterialGroupApi(){} - private static int saveChangeTask = -1; - private static int reloadChangeTask = -1; + private static Object saveChangeTask = null; + private static Object reloadChangeTask = null; /** @@ -180,28 +180,28 @@ public class MaterialGroupApi { * Prepare a task to reload every conflict. */ private static void prepareSaveTask() { - if(saveChangeTask != -1) return; + if(saveChangeTask != null) return; - saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true); - saveChangeTask = -1; - }, 0L); + saveChangeTask = null; + }); } /** * Prepare a task to save configuration. */ private static void prepareUpdateTask() { - if(reloadChangeTask != -1) return; + if(reloadChangeTask != null) return; - reloadChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + reloadChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.ITEM_GROUP_HOLDER.reload(); GroupConfigGui configGui = GroupConfigGui.getCurrentInstance(); if(configGui != null) configGui.reloadValues(); - reloadChangeTask = -1; - }, 0L); + reloadChangeTask = null; + }); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java b/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java index fe3c164..d471b19 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/UnitRepairApi.java @@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.api; import io.delilaheve.CustomAnvil; import kotlin.Triple; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.dependency.DependencyManager; import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui; @@ -23,7 +23,7 @@ public class UnitRepairApi { private UnitRepairApi(){} - private static int saveChangeTask = -1; + private static Object saveChangeTask = null; /** * Write and add a custom anvil unit repair recipe. @@ -161,12 +161,12 @@ public class UnitRepairApi { * Prepare a task to save custom unit repair recipe configuration. */ private static void prepareSaveTask() { - if(saveChangeTask != -1) return; + if(saveChangeTask != null) return; - saveChangeTask = Bukkit.getScheduler().scheduleSyncDelayedTask(CustomAnvil.instance, ()->{ + saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, ()->{ ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true); - saveChangeTask = -1; - }, 0L); + saveChangeTask = null; + }); } /** diff --git a/src/main/java/xyz/alexcrea/cuanvil/config/WorkPenaltyType.java b/src/main/java/xyz/alexcrea/cuanvil/config/WorkPenaltyType.java new file mode 100644 index 0000000..95edca6 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/config/WorkPenaltyType.java @@ -0,0 +1,114 @@ +package xyz.alexcrea.cuanvil.config; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; +import xyz.alexcrea.cuanvil.gui.config.settings.EnumSettingGui; + +import java.util.ArrayList; +import java.util.List; + +public enum WorkPenaltyType implements EnumSettingGui.ConfigurableEnum { + DEFAULT("default", true, true, "§aDefault", Material.LIME_TERRACOTTA), + ADDITIVE("add_only", false, true, "§eAdd Only", Material.YELLOW_TERRACOTTA), + INCREASE("increase_only", true, false, "§eIncrease Only", Material.YELLOW_TERRACOTTA), + DISABLED("disabled", false, false, "§cDisabled", Material.RED_TERRACOTTA), + ; + + private final String name; + private final boolean penaltyIncrease; + private final boolean penaltyAdditive; + + private final String configName; + private final Material configMaterial; + + WorkPenaltyType(String name, boolean penaltyIncrease, boolean penaltyAdditive, String configName, Material configMaterial) { + this.name = name; + this.penaltyIncrease = penaltyIncrease; + this.penaltyAdditive = penaltyAdditive; + this.configName = configName; + this.configMaterial = configMaterial; + } + + public boolean isPenaltyIncreasing() { + return penaltyIncrease; + } + + public boolean isPenaltyAdditive() { + return penaltyAdditive; + } + + private boolean doRepresentThisType(String toTest){ + return name.equalsIgnoreCase(toTest); + } + + @NotNull + public static WorkPenaltyType fromString(@Nullable String toTest){ + if(toTest == null) return DEFAULT; + + // Test if it matches any of values + for (WorkPenaltyType value : values()) { + if(value.doRepresentThisType(toTest)){ + return value; + } + } + + // Use default if not found + return DEFAULT; + } + + @NotNull + public static WorkPenaltyType next(@NotNull WorkPenaltyType now){ + return switch (now){ + case DEFAULT -> ADDITIVE; + case ADDITIVE -> INCREASE; + case INCREASE -> DISABLED; + case DISABLED -> DEFAULT; + + }; + + } + + @Override + public ItemStack configurationGuiItem() { + ItemStack displayedItem = new ItemStack(this.configMaterial); + ItemMeta valueMeta = displayedItem.getItemMeta(); + assert valueMeta != null; + + valueMeta.setDisplayName(this.configName); + + List lore = new ArrayList<>(); + + lore.add(configDisplayForAdd()); + lore.add(configDisplayForIncrease()); + lore.add(""); + + lore.add(AbstractSettingGui.CLICK_LORE); + valueMeta.setLore(lore); + + displayedItem.setItemMeta(valueMeta); + + return displayedItem; + } + + public String configDisplayForAdd(){ + return ("§7Add penalty: " + (penaltyAdditive ? "§aYes" : "§cNo")); + } + + public String configDisplayForIncrease(){ + return ("§7Increase penalty: " + (penaltyIncrease ? "§aYes" : "§cNo")); + } + + @Override + public String configName() { + return this.name; + } + + @Override + public String configurationGuiName() { + return this.configName; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java index 57ccb72..3718f39 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/EnchantmentRarity.java @@ -12,12 +12,12 @@ public class EnchantmentRarity { private final int itemValue; private final int bookValue; - public EnchantmentRarity(int itemValue, int bookValue) { + private EnchantmentRarity(int itemValue, int bookValue) { this.itemValue = itemValue; this.bookValue = bookValue; } - public EnchantmentRarity(int itemValue) { + private EnchantmentRarity(int itemValue) { this(itemValue, Math.max(1, itemValue / 2)); } @@ -29,4 +29,24 @@ public class EnchantmentRarity { return itemValue; } + + public static EnchantmentRarity getRarity(int itemValue, int bookValue){ + int expectedBook = Math.max(1, itemValue / 2); + if((expectedBook == bookValue) && (itemValue != 0)) return getRarity(itemValue); + + if(itemValue == 0 && bookValue == 0) return NO_RARITY; + return new EnchantmentRarity(itemValue, bookValue); + } + + public static EnchantmentRarity getRarity(int itemValue){ + return switch (itemValue) { + case 0 -> NO_RARITY; + case 1 -> COMMON; + case 2 -> UNCOMMON; + case 4 -> RARE; + case 8 -> VERY_RARE; + default -> new EnchantmentRarity(itemValue); + }; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java index 0f4a0e3..6b062aa 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java +++ b/src/main/java/xyz/alexcrea/cuanvil/enchant/wrapped/CABukkitEnchantment.java @@ -1,7 +1,9 @@ package xyz.alexcrea.cuanvil.enchant.wrapped; +import io.delilaheve.CustomAnvil; import io.delilaheve.util.ItemUtil; import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentTarget; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.ItemMeta; @@ -11,7 +13,12 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentBase; import xyz.alexcrea.cuanvil.enchant.EnchantmentProperties; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; import java.util.Locale; +import java.util.Map; +import java.util.logging.Level; /** * Custom Anvil enchantment implementation for vanilla registered enchantment. @@ -94,7 +101,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase { try { return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity(); } catch (IllegalArgumentException ignored) { - return EnchantmentRarity.COMMON; + return findRarity(enchantment); } } @@ -102,4 +109,52 @@ public class CABukkitEnchantment extends CAEnchantmentBase { protected Enchantment getEnchant() { return this.enchantment; } + + private static Method getAnvilCostMethod; + static { + Class clazz = Enchantment.class; + try { + getAnvilCostMethod = clazz.getDeclaredMethod("getAnvilCost"); + getAnvilCostMethod.setAccessible(true); + + CustomAnvil.Companion.log("Detected getAnvilCost method"); + } catch (NoSuchMethodException e) { + getAnvilCostMethod = null; + } + + } + + private static final Map targetToGroup = new HashMap<>(); + static { + targetToGroup.put(EnchantmentTarget.ARMOR, "armors"); + targetToGroup.put(EnchantmentTarget.ARMOR_HEAD, "helmets"); + targetToGroup.put(EnchantmentTarget.ARMOR_TORSO, "chestplate"); + targetToGroup.put(EnchantmentTarget.ARMOR_LEGS, "leggings"); + targetToGroup.put(EnchantmentTarget.ARMOR_FEET, "boots"); + targetToGroup.put(EnchantmentTarget.BOW, "bow"); + targetToGroup.put(EnchantmentTarget.BREAKABLE, "can_unbreak"); + targetToGroup.put(EnchantmentTarget.CROSSBOW, "crossbow"); + targetToGroup.put(EnchantmentTarget.FISHING_ROD, "fishing_rod"); + targetToGroup.put(EnchantmentTarget.TOOL, "tools"); + targetToGroup.put(EnchantmentTarget.TRIDENT, "trident"); + targetToGroup.put(EnchantmentTarget.VANISHABLE, "can_vanish"); + targetToGroup.put(EnchantmentTarget.WEAPON, "swords"); + targetToGroup.put(EnchantmentTarget.WEARABLE, "wearable"); + } + + private static EnchantmentRarity findRarity(Enchantment enchantment) { + if(getAnvilCostMethod == null) return EnchantmentRarity.COMMON; + + try { + int itemCost = (int) getAnvilCostMethod.invoke(enchantment); + + return EnchantmentRarity.getRarity(itemCost); + } catch (IllegalAccessException | InvocationTargetException e) { + CustomAnvil.instance.getLogger().log(Level.SEVERE, "could not find cost for enchantment "+enchantment.getKey(), e); + + return EnchantmentRarity.COMMON; + } + + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java index 235e1d4..4f98cc3 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java @@ -11,6 +11,7 @@ import org.bukkit.inventory.meta.ItemMeta; import xyz.alexcrea.cuanvil.dependency.packet.PacketManager; import xyz.alexcrea.cuanvil.gui.config.global.*; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; +import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import java.util.Collections; @@ -28,7 +29,7 @@ public class MainConfigGui extends ChestGui { public void init(PacketManager packetManager) { Pattern pattern = new Pattern( - "000000000", + GuiSharedConstant.EMPTY_GUI_FULL_LINE, "012304567", "Q00000000" ); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index 246f2eb..b2d6afe 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -71,7 +71,7 @@ public class SelectItemTypeGui extends AbstractAskGui { this.pane.bindItem('V', selectGuiItem.get()); // Temporary leave item - GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_TERRACOTTA, this); + GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this); this.pane.bindItem('s', temporaryLeave); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java index f9e2903..a65b54b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/AbstractEnchantConfigGui.java @@ -44,11 +44,11 @@ public abstract class AbstractEnchantConfigGui workPenaltyType; // W character + private BoolSettingsGui.BoolSettingFactory allowColorCode; // c character private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character @@ -99,7 +104,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { */ protected void prepareValues() { // cap anvil cost - this.capAnvilCost = BoolSettingsGui.boolFactory("§8Cap Anvil Cost ?", this, + this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory("§8Cap Anvil Cost ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, "§7All anvil cost will be capped to §aMax Anvil Cost§7 if enabled.", @@ -118,7 +123,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // repair cost item IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; - this.maxAnvilCost = IntSettingsGui.intFactory("§8Max Anvil Cost", this, + this.maxAnvilCost = new IntSettingsGui.IntSettingFactory("§8Max Anvil Cost", this, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7Max cost the Anvil can get to.", @@ -142,7 +147,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // remove repair limit item - this.removeAnvilCostLimit = BoolSettingsGui.boolFactory("§8Remove Anvil Cost Limit ?", this, + this.removeAnvilCostLimit = new BoolSettingsGui.BoolSettingFactory("§8Remove Anvil Cost Limit ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT, "§7Whether the anvil's cost limit should be removed entirely.", @@ -150,7 +155,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { "§7However, the action will be completable if xp requirement is meet."); // replace too expensive item - this.replaceTooExpensive = BoolSettingsGui.boolFactory("§8Replace Too Expensive ?", this, + this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory("§8Replace Too Expensive ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, getReplaceToExpensiveLore()); @@ -161,7 +166,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // item repair cost range = ConfigOptions.REPAIR_COST_RANGE; - this.itemRepairCost = IntSettingsGui.intFactory("§8Item Repair Cost", this, + this.itemRepairCost = new IntSettingsGui.IntSettingFactory("§8Item Repair Cost", this, ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7XP Level amount added to the anvil when the item", @@ -172,7 +177,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { 1, 5, 10, 50, 100); // unit repair cost - this.unitRepairCost = IntSettingsGui.intFactory("§8Unit Repair Cost", this, + this.unitRepairCost = new IntSettingsGui.IntSettingFactory("§8Unit Repair Cost", this, ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7XP Level amount added to the anvil when the item is repaired by an §eunit§7.", @@ -185,7 +190,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // item rename cost range = ConfigOptions.ITEM_RENAME_COST_RANGE; - this.itemRenameCost = IntSettingsGui.intFactory("§8Rename Cost", this, + this.itemRenameCost = new IntSettingsGui.IntSettingFactory("§8Rename Cost", this, ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7XP Level amount added to the anvil when the item is renamed." @@ -196,7 +201,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // sacrifice illegal enchant cost range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE; - this.sacrificeIllegalEnchantCost = IntSettingsGui.intFactory("§8Sacrifice Illegal Enchant Cost", this, + this.sacrificeIllegalEnchantCost = new IntSettingsGui.IntSettingFactory("§8Sacrifice Illegal Enchant Cost", this, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7XP Level amount added to the anvil when a sacrifice enchantment", @@ -206,12 +211,52 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, 1, 5, 10, 50, 100); + // ------------- + // Work Penalty + // ------------- + + this.workPenaltyType = new EnumSettingGui.EnumSettingFactory<>("§8Work Penalty Type", this, + ConfigOptions.WORK_PENALTY_TYPE, ConfigHolder.DEFAULT_CONFIG + ) { + @NotNull + @Override + public WorkPenaltyType getConfiguredValue() { + return ConfigOptions.INSTANCE.getWorkPenaltyType(); + } + + @NotNull + @Override + public WorkPenaltyType getDefault() { + return WorkPenaltyType.DEFAULT; + } + + @NotNull + @Override + public List getDisplayLore(WorkPenaltyType value) { + return List.of( + "§7Work penalty increase the price for every anvil use.", + "§7This config allow you to choose the comportment of work penalty.", + "", + value.configDisplayForAdd(), + value.configDisplayForIncrease() + + ); + } + + @NotNull + @Override + public WorkPenaltyType next(@NotNull WorkPenaltyType now) { + return WorkPenaltyType.next(now); + } + + }; + // ------------- // Color config // ------------- // Allow us of color code - this.allowColorCode = BoolSettingsGui.boolFactory("§8Allow Use Of Color Code ?", this, + this.allowColorCode = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Color Code ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, "§7Whether players can use color code.", @@ -219,7 +264,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { "§7Player may need permission to use color code if §ePlayer need permission to use color§7 is enabled."); // Allow us of hexadecimal color - this.allowHexColor = BoolSettingsGui.boolFactory("§8Allow Use Of Hexadecimal Color ?", this, + this.allowHexColor = new BoolSettingsGui.BoolSettingFactory("§8Allow Use Of Hexadecimal Color ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, "§7Whether players can use hexadecimal color.", @@ -227,7 +272,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { "§7Player may need permission to use color code if §ePermission Needed For Color§7 is enabled."); // Permission needed for color - this.permissionNeededForColor = BoolSettingsGui.boolFactory("§8Need Permission To Use Color ?", this, + this.permissionNeededForColor = new BoolSettingsGui.BoolSettingFactory("§8Need Permission To Use Color ?", this, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, "§7Whether players should have permission to be able to use colors.", @@ -248,7 +293,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { // Cost of using color range = ConfigOptions.USE_OF_COLOR_COST_RANGE; - this.useOfColorCost = IntSettingsGui.intFactory("§8Cost Of Using Color", this, + this.useOfColorCost = new IntSettingsGui.IntSettingFactory("§8Cost Of Using Color", this, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG, Arrays.asList( "§7XP level cost when using color code or hexadecimal color using the anvil.", @@ -331,6 +376,10 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui { GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK); pane.bindItem('S', illegalCostItem); + // work penalty type + GuiItem workPenaltyType = this.workPenaltyType.getItem(Material.DAMAGED_ANVIL, "§aWork Penalty Type"); + pane.bindItem('W', workPenaltyType); + // allow color code GuiItem allowColorCodeItem = this.allowColorCode.getItem(); pane.bindItem('c', allowColorCodeItem); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java index f06d364..0aaf0ee 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java @@ -40,7 +40,7 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui extends ChestGui implements Valu protected PatternPane backgroundPane; - protected ElementListConfigGui(@NotNull String title) { + public static final int LIST_FILLER_START_X = 1; + public static final int LIST_FILLER_START_Y = 1; + public static final int LIST_FILLER_LENGTH = 7; + public static final int LIST_FILLER_HEIGHT = 4; + + protected ElementListConfigGui(@NotNull String title, Gui parent) { super(6, title, CustomAnvil.instance); this.namePrefix = title; // Back item panel Pattern pattern = getBackgroundPattern(); this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern); - GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.getInstance()); + GuiGlobalItems.addBackItem(this.backgroundPane, parent); } protected Pattern getBackgroundPattern(){ return new Pattern( - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.UPPER_FILLER_FULL_PLANE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, "B11L1R11C" ); } @@ -79,7 +83,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected void prepareStaticValues(){ // Left item creation for consumer & bind - this.goLeftItem = new GuiItem(new ItemStack(Material.RED_TERRACOTTA), event -> { + this.goLeftItem = new GuiItem(new ItemStack(Material.RED_STAINED_GLASS_PANE), event -> { HumanEntity viewer = event.getWhoClicked(); UUID playerUUID = viewer.getUniqueId(); int page = this.pageMap.getOrDefault(playerUUID, 0); @@ -94,7 +98,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu }, CustomAnvil.instance); // Right item creation for consumer & bind - this.goRightItem = new GuiItem(new ItemStack(Material.GREEN_TERRACOTTA), event -> { + this.goRightItem = new GuiItem(new ItemStack(Material.LIME_STAINED_GLASS_PANE), event -> { HumanEntity viewer = event.getWhoClicked(); UUID playerUUID = viewer.getUniqueId(); int page = pageMap.getOrDefault(playerUUID, 0); @@ -128,7 +132,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected abstract GuiItem prepareCreateNewItem(); protected OutlinePane createEmptyPage() { - OutlinePane page = new OutlinePane(0, 0, 9, 5); + OutlinePane page = new OutlinePane(LIST_FILLER_START_X, LIST_FILLER_START_Y, LIST_FILLER_LENGTH, LIST_FILLER_HEIGHT); page.align(OutlinePane.Alignment.BEGIN); page.setOrientation(Orientable.Orientation.HORIZONTAL); @@ -146,7 +150,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu protected void addToPage(GuiItem guiItem) { // Get first available page or create one OutlinePane page = this.pages.get(this.pages.size() - 1); - if (page.getItems().size() >= 5 * 9) { + if (page.getItems().size() >= LIST_FILLER_LENGTH * LIST_FILLER_HEIGHT) { page = createEmptyPage(); this.pages.add(page); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java index ced5fd2..31ab718 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java @@ -7,6 +7,7 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import java.util.Arrays; @@ -17,7 +18,7 @@ public abstract class MappedElementListConfigGui< T, S > extends ElementListConf protected final HashMap elementGuiMap; protected MappedElementListConfigGui(@NotNull String title) { - super(title); + super(title, MainConfigGui.getInstance()); this.elementGuiMap = new HashMap<>(); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java index 808b40d..f0e7cb0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java @@ -1,12 +1,14 @@ package xyz.alexcrea.cuanvil.gui.config.list; import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.bukkit.Material; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import java.util.HashMap; @@ -17,12 +19,16 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu protected HashMap guiItemMap; protected HashMap factoryMap; - protected SettingGuiListConfigGui(@NotNull String title) { - super(title); + protected SettingGuiListConfigGui(@NotNull String title, Gui parent) { + super(title, parent); this.guiItemMap = new HashMap<>(); this.factoryMap = new HashMap<>(); } + protected SettingGuiListConfigGui(@NotNull String title) { + this(title, MainConfigGui.getInstance()); + } + @Override protected GuiItem prepareCreateNewItem() { ItemStack createItem = new ItemStack(Material.PAPER); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java index 9a16aa4..0bf2a03 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java @@ -112,7 +112,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui displayLore, - int scale, boolean asPercentage, boolean nullOnZero, - double min, double max, double defaultVal, double... steps) { - return new DoubleSettingFactory( - title, parent, - config, - configPath, - displayLore, - scale, asPercentage, nullOnZero, - min, max, defaultVal, steps); - } - /** * A factory for a double setting gui that hold setting's information. */ @@ -427,7 +391,7 @@ public class DoubleSettingGui extends AbstractSettingGui { * it is visually preferable to have an odd number of step. * If step only contain 1 value, no step item should be displayed. */ - protected DoubleSettingFactory( + public DoubleSettingFactory( @NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull ConfigHolder config, @NotNull String configPath, diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java index 71a31d9..176da55 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantSelectSettingGui.java @@ -15,6 +15,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; +import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; @@ -35,7 +36,7 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui(enchantContainer.getSelectedEnchantments()); @@ -52,11 +53,11 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui & EnumSettingGui.ConfigurableEnum> extends AbstractSettingGui { + + private final EnumSettingFactory holder; + private final T before; + private T now; + + /** + * Create an item setting config gui. + * + * @param holder Configuration factory of this setting. + * @param now The defined value of this setting. + */ + protected EnumSettingGui(EnumSettingFactory holder, T now) { + super(3, holder.getTitle(), holder.parent); + this.holder = holder; + this.before = now; + this.now = now; + + prepareStaticItems(); + updateValueDisplay(); + } + + @Override + public Pattern getGuiPattern() { + return new Pattern( + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + "D000v0000", + "B0000000S" + ); + } + + + public void prepareStaticItems(){ + prepareReturnToDefault(); + } + + + protected GuiItem returnToDefault; + + /** + * Prepare "return to default value" gui item. + */ + protected void prepareReturnToDefault() { + ItemStack item = new ItemStack(Material.COMMAND_BLOCK); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("§eReset to default value"); + meta.setLore(Collections.singletonList("§7Default value is §e" + holder.getDefault().configurationGuiName())); + item.setItemMeta(meta); + returnToDefault = new GuiItem(item, event -> { + event.setCancelled(true); + now = holder.getDefault(); + updateValueDisplay(); + update(); + }, CustomAnvil.instance); + } + + /** + * Update item using the setting value to match the new value + */ + protected void updateValueDisplay() { + PatternPane pane = getPane(); + + // Get displayed value for this config. + ItemStack displayedItem = now.configurationGuiItem(); + + GuiItem resultItem = new GuiItem(displayedItem, selectNext(), CustomAnvil.instance); + pane.bindItem('v', resultItem); + + // reset to default + GuiItem returnToDefault; + if (now != holder.getDefault()) { + returnToDefault = this.returnToDefault; + } else { + returnToDefault = GuiGlobalItems.backgroundItem(); + } + pane.bindItem('D', returnToDefault); + + } + + /** + * @return A consumer to update the current setting's value. + */ + protected Consumer selectNext() { + return event -> { + event.setCancelled(true); + + this.now = this.holder.next(this.now); + + updateValueDisplay(); + update(); + }; + + } + + @Override + public boolean onSave() { + holder.config.getConfig().set(holder.configPath, this.now.configName()); + + if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { + return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + } + return true; + } + + @Override + public boolean hadChange() { + return !now.equals(before); + } + + + /** + * A factory for an enum setting gui that hold setting's information. + */ + public abstract static class EnumSettingFactory & ConfigurableEnum> extends SettingGuiFactory { + @NotNull + String title; + @NotNull + ValueUpdatableGui parent; + + /** + * Constructor for an enum settings gui factory + * + * @param title The title of the gui. + * @param parent Parent gui to go back when completed. + * @param configPath Configuration path of this setting. + * @param config Configuration holder of this setting. + */ + protected EnumSettingFactory( + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config) { + super(configPath, config); + this.title = title; + this.parent = parent; + + } + /** + * @return Get setting's gui title. + */ + @NotNull + public String getTitle() { + return title; + } + + /** + * @return The configured value for the associated setting. + */ + @NotNull + public abstract T getConfiguredValue(); + + @NotNull + public abstract List getDisplayLore(T value); + + /** + * @return Next value for a given enum + */ + @NotNull + public T next(@NotNull T now){ + Class clazz = now.getDeclaringClass(); + T[] values = clazz.getEnumConstants(); + + int index = now.ordinal(); + if(index == values.length - 1) + return values[0]; + + return values[index + 1]; + } + + /** + * Get default value value + * @return default value + */ + @NotNull + public abstract T getDefault(); + + @Override + public Gui create() { + // Get value or default + T now = getConfiguredValue(); + + // create new gui + return new EnumSettingGui<>(this, now); + } + + /** + * Create a new enum setting GuiItem. + * This item will create and open an enum setting GUI from the factory. + * + * @param name Name of the display. + * @return A formatted GuiItem that will create and open a GUI for the enum setting. + */ + public GuiItem getItem(@NotNull Material material, @NotNull String name) { + T value = getConfiguredValue(); + + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName(name); + meta.setLore(getDisplayLore(value)); + meta.addItemFlags(ItemFlag.values()); + + item.setItemMeta(meta); + + return GuiGlobalItems.openSettingGuiItem(item, this); + } + } + + public interface ConfigurableEnum { + + String configName(); + + ItemStack configurationGuiItem(); + String configurationGuiName(); + + + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java index d5d768a..69986a0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java @@ -17,6 +17,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; +import xyz.alexcrea.cuanvil.gui.config.list.ElementListConfigGui; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.util.CasedStringUtil; @@ -50,18 +51,22 @@ public class GroupSelectSettingGui extends AbstractSettingGui { @Override protected Pattern getGuiPattern() { return new Pattern( - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, - GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.UPPER_FILLER_FULL_PLANE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, + GuiSharedConstant.EMPTY_FILLER_FULL_LINE, "B1111111S" ); } protected void initGroups() { // Add enchantment gui item - OutlinePane filledEnchant = new OutlinePane(0, 0, 9, 5); + OutlinePane filledEnchant = new OutlinePane( + ElementListConfigGui.LIST_FILLER_START_X, + ElementListConfigGui.LIST_FILLER_START_Y, + ElementListConfigGui.LIST_FILLER_LENGTH, + ElementListConfigGui.LIST_FILLER_HEIGHT); filledEnchant.setPriority(Pane.Priority.HIGH); filledEnchant.align(OutlinePane.Alignment.BEGIN); filledEnchant.setOrientation(Orientable.Orientation.HORIZONTAL); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java index 8a9059f..af977e9 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java @@ -275,38 +275,11 @@ public class IntSettingsGui extends AbstractSettingGui { return now != before; } - /** - * Create an int setting factory from setting's parameters. - * - * @param title The title of the gui. - * @param parent Parent gui to go back when completed. - * @param configPath Configuration path of this setting. - * @param config Configuration holder of this setting. - * @param displayLore Gui display item lore. - * @param min Minimum value of this setting. - * @param max Maximum value of this setting. - * @param defaultVal Default value if not found on the config. - * @param steps List of step the value can increment/decrement. - * List's size should be between 1 (included) and 5 (included). - * it is visually preferable to have an odd number of step. - * If step only contain 1 value, no step item should be displayed. - * @return A factory for an int setting gui. - */ - public static IntSettingFactory intFactory(@NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, - @Nullable List displayLore, - int min, int max, int defaultVal, int... steps) { - return new IntSettingFactory( - title, parent, - configPath, config, - displayLore, - min, max, defaultVal, steps); - } - /** * A factory for an int setting gui that hold setting's information. */ public static class IntSettingFactory extends SettingGuiFactory { + @NotNull String title; @NotNull @@ -335,7 +308,7 @@ public class IntSettingsGui extends AbstractSettingGui { * it is visually preferable to have an odd number of step. * If step only contain 1 value, no step item should be displayed. */ - protected IntSettingFactory( + public IntSettingFactory( @NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, @Nullable List displayLore, diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java index 80f697b..3df2af8 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java @@ -62,7 +62,7 @@ public class ItemSettingGui extends AbstractSettingGui { public void prepareStaticItems(){ prepareReturnToDefault(); - GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_TERRACOTTA, this); + GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this); getPane().bindItem('s', temporaryLeave); } @@ -163,27 +163,6 @@ public class ItemSettingGui extends AbstractSettingGui { return !now.equals(before); } - /** - * Create aa item setting factory from setting's parameters. - * - * @param title The title of the gui. - * @param parent Parent gui to go back when completed. - * @param configPath Configuration path of this setting. - * @param config Configuration holder of this setting. - * @param defaultVal Default value if not found on the config. - * @param displayLore Gui display item lore. - * @return A factory for an item setting gui. - */ - public static ItemSettingGui.ItemSettingFactory itemFactory(@NotNull String title, @NotNull ValueUpdatableGui parent, - @NotNull String configPath, @NotNull ConfigHolder config, - @Nullable ItemStack defaultVal, - String... displayLore) { - return new ItemSettingGui.ItemSettingFactory( - title, parent, - configPath, config, - defaultVal, displayLore); - } - /** * A factory for an item setting gui that hold setting's information. */ @@ -207,7 +186,7 @@ public class ItemSettingGui extends AbstractSettingGui { * @param defaultVal Default value if not found on the config. * @param displayLore Gui display item lore. */ - protected ItemSettingFactory( + public ItemSettingFactory( @NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String configPath, @NotNull ConfigHolder config, @Nullable ItemStack defaultVal, diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java index 9d10d59..a3963ce 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java @@ -57,11 +57,11 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui 0){ + CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values."); + ConfigHolder.DEFAULT_CONFIG.saveToDisk(true); + } + + } + + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, @NotNull String value){ + if(config.isSet(path)) return 0; + + config.set(path, value); + return 1; + } + + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, int value){ + if(config.isSet(path)) return 0; + + config.set(path, value); + return 1; + } + + private static int trySetDefault(@NotNull FileConfiguration config, @NotNull String path, boolean value){ + if(config.isSet(path)) return 0; + + config.set(path, value); + return 1; + } + + +} diff --git a/src/main/kotlin/io/delilaheve/CustomAnvil.kt b/src/main/kotlin/io/delilaheve/CustomAnvil.kt index 9d5d803..935a104 100644 --- a/src/main/kotlin/io/delilaheve/CustomAnvil.kt +++ b/src/main/kotlin/io/delilaheve/CustomAnvil.kt @@ -14,6 +14,7 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.listener.ChatEventListener +import xyz.alexcrea.cuanvil.update.PluginSetDefault import xyz.alexcrea.cuanvil.update.Update_1_21 import xyz.alexcrea.cuanvil.util.Metrics import java.io.File @@ -115,7 +116,7 @@ class CustomAnvil : JavaPlugin() { // Load other thing later. // It is so other dependent plugins can implement there event listener before we fire them. - Bukkit.getScheduler().scheduleSyncDelayedTask(this, {loadEnchantmentSystem()}, 0L) + DependencyManager.scheduler.scheduleGlobally(this, {loadEnchantmentSystem()}) } private fun loadEnchantmentSystem(){ @@ -146,6 +147,9 @@ class CustomAnvil : JavaPlugin() { MainConfigGui.getInstance().init(DependencyManager.packetManager) GuiSharedConstant.loadConstants() + // Finally, re add default we may be missing + PluginSetDefault.reAddMissingDefault() + } fun reloadResource( diff --git a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt index 80dea06..37fdf5a 100644 --- a/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt +++ b/src/main/kotlin/io/delilaheve/util/ConfigOptions.kt @@ -3,6 +3,7 @@ package io.delilaheve.util import io.delilaheve.CustomAnvil import io.delilaheve.util.EnchantmentUtil.enchantmentName import xyz.alexcrea.cuanvil.config.ConfigHolder +import xyz.alexcrea.cuanvil.config.WorkPenaltyType import xyz.alexcrea.cuanvil.enchant.CAEnchantment /** @@ -33,7 +34,9 @@ object ConfigOptions { 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" + const val WORK_PENALTY_TYPE = "work_penalty_type" + + const val DEFAULT_LIMIT_PATH = "default_limit" const val ENCHANT_LIMIT_ROOT = "enchant_limits" const val ENCHANT_VALUES_ROOT = "enchant_values" @@ -69,7 +72,7 @@ object ConfigOptions { const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true const val DEFAULT_USE_OF_COLOR_COST = 0 - private const val DEFAULT_ENCHANT_LIMIT = 5 + const val DEFAULT_ENCHANT_LIMIT = 5 // Debug flag private const val DEFAULT_DEBUG_LOG = false @@ -248,6 +251,17 @@ object ConfigOptions { ?: DEFAULT_USE_OF_COLOR_COST } + /** + * How many xp should use of color should cost + */ + val workPenaltyType: WorkPenaltyType + get() { + return WorkPenaltyType.fromString( + ConfigHolder.DEFAULT_CONFIG + .config + .getString(WORK_PENALTY_TYPE)); + } + /** * Default enchantment limit */ diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt index e05a4f2..85761d9 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/EditConfigExecutor.kt @@ -5,6 +5,7 @@ import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.HumanEntity +import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions @@ -15,6 +16,15 @@ class EditConfigExecutor : CommandExecutor { sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) return false } + if(DependencyManager.isFolia){ + sender.sendMessage("§cIt look like you are using Folia. Sadly Custom Anvil do not support Config gui for Folia.") + sender.sendMessage("§eIt is may come in a future version.") + sender.sendMessage("") + sender.sendMessage("§eCurrently you need to edit manually the config or copy from another server (spigot or better)") + sender.sendMessage("§eThen /anvilconfigreload after config file is edited") + return false + } + if (sender !is HumanEntity) return false MainConfigGui.getInstance().show(sender) diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt index 749f10b..f122068 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt @@ -1,5 +1,6 @@ package xyz.alexcrea.cuanvil.dependency +import io.delilaheve.CustomAnvil import org.bukkit.Bukkit import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.PrepareAnvilEvent @@ -7,9 +8,14 @@ import org.bukkit.inventory.AnvilInventory import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector +import xyz.alexcrea.cuanvil.dependency.scheduler.BukkitScheduler +import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler +import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler object DependencyManager { + var isFolia: Boolean = false + lateinit var scheduler: TaskScheduler lateinit var packetManager: PacketManager var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null var ecoEnchantCompatibility: EcoEnchantDependency? = null @@ -18,6 +24,14 @@ object DependencyManager { fun loadDependency(){ val pluginManager = Bukkit.getPluginManager() + // Bukkit or Paper scheduler ? + isFolia = testIsFolia() + scheduler = if(isFolia) { + CustomAnvil.instance.logger.info("Folia detected... Custom Anvil Folia support is experimental. issues are more likely to happens.") + + FoliaScheduler() + } else BukkitScheduler() + // Packet Manager val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.config.getBoolean("force_protocolib", false) packetManager = PacketManagerSelector.selectPacketManager(forceProtocolib) @@ -78,4 +92,14 @@ object DependencyManager { return bypass } + + private fun testIsFolia(): Boolean { + try { + Class.forName("io.papermc.paper.threadedregions.RegionizedServer") + return true + } catch (e: ClassNotFoundException) { + return false + } + } + } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DisenchantmentDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DisenchantmentDependency.kt index 278e3ef..be27c05 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DisenchantmentDependency.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DisenchantmentDependency.kt @@ -1,9 +1,9 @@ package xyz.alexcrea.cuanvil.dependency -import cz.kominekjan.disenchantment.events.ItemClickEvent -import cz.kominekjan.disenchantment.events.ItemEvent -import cz.kominekjan.disenchantment.events.SplitBookClickEvent -import cz.kominekjan.disenchantment.events.SplitBookEvent +import cz.kominekjan.disenchantment.events.DisenchantClickEvent +import cz.kominekjan.disenchantment.events.DisenchantEvent +import cz.kominekjan.disenchantment.events.ShatterClickEvent +import cz.kominekjan.disenchantment.events.ShatterEvent import io.delilaheve.AnvilEventListener import io.delilaheve.CustomAnvil import org.bukkit.event.inventory.InventoryClickEvent @@ -19,11 +19,11 @@ class DisenchantmentDependency { CustomAnvil.instance.logger.info("Disenchantment Detected !") } - private lateinit var splitEvent: SplitBookEvent - private lateinit var itemEvent: ItemEvent + private lateinit var splitEvent: ShatterEvent + private lateinit var itemEvent: DisenchantEvent - private lateinit var splitBookClickEvent: SplitBookClickEvent - private lateinit var itemClickEvent: ItemClickEvent + private lateinit var splitBookClickEvent: ShatterClickEvent + private lateinit var itemClickEvent: DisenchantClickEvent fun redirectListeners() { @@ -32,12 +32,12 @@ class DisenchantmentDependency { for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) { val listener = registeredListener.listener - if(listener is SplitBookEvent){ + if(listener is ShatterEvent){ this.splitEvent = listener toUnregister.add(registeredListener) } - if(listener is ItemEvent){ + if(listener is DisenchantEvent){ itemEvent = listener toUnregister.add(registeredListener) } @@ -53,12 +53,12 @@ class DisenchantmentDependency { for (registeredListener in InventoryClickEvent.getHandlerList().registeredListeners) { val listener = registeredListener.listener - if(listener is SplitBookClickEvent){ + if(listener is ShatterClickEvent){ splitBookClickEvent = listener toUnregister.add(registeredListener) } - if(listener is ItemClickEvent){ + if(listener is DisenchantClickEvent){ itemClickEvent = listener toUnregister.add(registeredListener) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt new file mode 100644 index 0000000..b26dd42 --- /dev/null +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/scheduler/BukkitScheduler.kt @@ -0,0 +1,17 @@ +package xyz.alexcrea.cuanvil.dependency.scheduler + +import org.bukkit.Bukkit +import org.bukkit.entity.Entity +import org.bukkit.plugin.Plugin + +class BukkitScheduler : TaskScheduler { + + override fun scheduleGlobally(plugin: Plugin, task: Runnable, time: Long): Any? { + return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time) + } + + + override fun scheduleOnEntity(plugin: Plugin, entity: Entity, task: Runnable, time: Long): Any? { + return Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, task, time) + } +} diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt index 4ea85fd..f166fa3 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/ChatEventListener.kt @@ -1,12 +1,12 @@ package xyz.alexcrea.cuanvil.listener import io.delilaheve.CustomAnvil -import org.bukkit.Bukkit import org.bukkit.entity.HumanEntity import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.player.AsyncPlayerChatEvent import org.bukkit.event.player.PlayerQuitEvent +import xyz.alexcrea.cuanvil.dependency.DependencyManager import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.function.Consumer @@ -39,9 +39,11 @@ class ChatEventListener : Listener { event.isCancelled = true // sync callback with default server thread - Bukkit.getScheduler().runTask(CustomAnvil.instance, Runnable { + DependencyManager.scheduler.scheduleOnEntity( + CustomAnvil.instance, player, + Runnable { eventCallback.accept(event.message) - }) + }, 0L) } } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt index 8b949ab..bdbc8bd 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/util/AnvilXpUtil.kt @@ -38,21 +38,20 @@ object AnvilXpUtil { anvilCost } + val player = view.player + /* Because Minecraft likes to have the final say in the repair cost displayed * we need to wait for the event to end before overriding it, this ensures that * we have the final say in the process. */ - CustomAnvil.instance - .server - .scheduler - .runTask(CustomAnvil.instance, Runnable { + DependencyManager.scheduler.scheduleOnEntity( + CustomAnvil.instance, player, + Runnable { inventory.maximumRepairCost = if (ConfigOptions.doRemoveCostLimit || ignoreRules) { Int.MAX_VALUE } else { ConfigOptions.maxAnvilCost + 1 } - val player = view.player - inventory.repairCost = finalAnvilCost view.setProperty(REPAIR_COST, finalAnvilCost) player.openInventory.setProperty(REPAIR_COST, finalAnvilCost) @@ -85,16 +84,17 @@ object AnvilXpUtil { fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack, unitRepair: Boolean): Int { // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation // Calculate work penalty + val penaltyType = ConfigOptions.workPenaltyType; 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 + // Increase penalty on fusing or unit repair - if(right != null || unitRepair){ + if(penaltyType.isPenaltyIncreasing && (right != null || unitRepair)){ result.itemMeta?.let { (it as? Repairable)?.repairCost = leftPenalty * 2 + 1 result.itemMeta = it @@ -109,6 +109,8 @@ object AnvilXpUtil { "result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}" ) + if(!penaltyType.isPenaltyAdditive) return 0 + return leftPenalty + rightPenalty } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index bb4f05f..09f142c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -72,6 +72,18 @@ permission_needed_for_color: true # Valid values include 0 to 1000. use_of_color_cost: 0 +# Work penalty increase the price for every anvil use. +# This config allow you to choose the comportment of work penalty. +# Vanilla work penalty formula can be represented as 2 * previous_penalty + 1. with start value equal to 0 +# See https://minecraft.wiki/w/Anvil_mechanics#Anvil_uses for more detail +# +# Valid work penalty type is: +# - default: work penalty added and increased +# - increase_only: work penalty increased but not added +# - add_only: work penalty added but not increased +# - disabled: work penalty disabled +work_penalty_type: default + # Default limit to apply to any enchants missing from enchant_limits # # Valid values include 1 to 1000 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9446af8..c7f2a01 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,8 @@ main: io.delilaheve.CustomAnvil name: CustomAnvil prefix: "Custom Anvil" -version: 1.6.0 +version: 1.6.1 +folia-supported: true description: Allow to customise anvil mechanics api-version: 1.16 load: POSTWORLD