- Fixed "chose enchantments of conflict" gui back button not leading to previous gui
- Tried to make list guis pretiers
- Better default item and book cost on paper
- Fix custom craft exact count button not working
- Add work penalty type (Future version may allow custom penalty type)
- Experimental Folia support
- Compatibility with [Disenchantment](https://www.spigotmc.org/resources/disenchantment-1-21-1-1-20-6-new-book-splitting-mechanics.110741/) 5.4.0 (but break compatibility with version under 5.4.0)
- Automatically add default to config.yml when they are absent
This commit is contained in:
alexcrea 2024-09-13 14:50:44 +02:00 committed by GitHub
commit 9aef871241
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 868 additions and 264 deletions

View file

@ -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) - Can handle some custom enchantment plugins (see below for more information)
- Gui to configure the plugin in game. - Gui to configure the plugin in game.
- Support of color code and hexadecimal color - Support of color code and hexadecimal color
- (Experimental) folia support (gui do not work)
--- ---
### Permissions: ### Permissions:
```yml ```yml
@ -59,7 +60,7 @@ Use EcoEnchant restriction system by default.
Here is a list of supported anvil mechanic plugins with support status: 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/) - [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). 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 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. 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: ### Planned:
- Semi manual config update on plugin or minecraft update - Better folia support (make gui work. fix some dirty handled parts)
- Get restriction and multiplier on unknown enchantments - Get restriction on unknown enchantments
- Warn admin on unsupported minecraft version - Warn admin on unsupported minecraft version
- More features for custom anvil craft - More features for custom anvil craft
### Known issue: ### Known issue:
Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta. Most unknown registered enchantments (by unsupported custom enchantment plugin & datapacks) will not have restriction by default. Planned but no eta.

View file

@ -14,7 +14,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.6.0" version = "1.6.1"
repositories { repositories {
// EcoEnchants // EcoEnchants
@ -37,7 +37,7 @@ dependencies {
compileOnly("com.willfp:eco:6.70.1") compileOnly("com.willfp:eco:6.70.1")
// Disenchantment // Disenchantment
compileOnly("cz.kominekjan:Disenchantment:v5.3.1") compileOnly("cz.kominekjan:Disenchantment:v5.4.0")
// Include nms // Include nms
implementation(project(":nms:nms-common")) implementation(project(":nms:nms-common"))

View file

@ -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)
}
}

View file

@ -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
)
}
}

View file

@ -1,11 +1,11 @@
package xyz.alexcrea.cuanvil.api; package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup; import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui; import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui;
@ -21,8 +21,8 @@ public class ConflictAPI {
private ConflictAPI() {} private ConflictAPI() {}
private static int saveChangeTask = -1; private static Object saveChangeTask = null;
private static int reloadChangeTask = -1; private static Object reloadChangeTask = null;
/** /**
* Write and add a conflict. * Write and add a conflict.
@ -151,27 +151,27 @@ public class ConflictAPI {
* Prepare a task to save conflict configuration. * Prepare a task to save conflict configuration.
*/ */
private static void prepareSaveTask() { 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); ConfigHolder.CONFLICT_HOLDER.saveToDisk(true);
saveChangeTask = -1; saveChangeTask = null;
}, 0L); });
} }
/** /**
* Prepare a task to reload every conflict. * Prepare a task to reload every conflict.
*/ */
private static void prepareUpdateTask() { 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(); ConfigHolder.CONFLICT_HOLDER.reload();
EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance(); EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance();
if(conflictGui != null) conflictGui.reloadValues(); if(conflictGui != null) conflictGui.reloadValues();
reloadChangeTask = -1; reloadChangeTask = null;
}, 0L); });
} }

View file

@ -1,10 +1,10 @@
package xyz.alexcrea.cuanvil.api; package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui; import xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui;
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
@ -19,7 +19,7 @@ public class CustomAnvilRecipeApi {
private CustomAnvilRecipeApi(){} private CustomAnvilRecipeApi(){}
private static int saveChangeTask = -1; private static Object saveChangeTask = null;
/** /**
* Write and add a custom anvil recipe. * Write and add a custom anvil recipe.
@ -103,12 +103,12 @@ public class CustomAnvilRecipeApi {
* Prepare a task to save custom recipe configuration. * Prepare a task to save custom recipe configuration.
*/ */
private static void prepareSaveTask() { 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); ConfigHolder.CONFLICT_HOLDER.saveToDisk(true);
saveChangeTask = -1; saveChangeTask = null;
}, 0L); });
} }
/** /**

View file

@ -1,13 +1,13 @@
package xyz.alexcrea.cuanvil.api; package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
@ -26,7 +26,7 @@ import java.util.Map;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class EnchantmentApi { public class EnchantmentApi {
private static int saveChangeTask = -1; private static Object saveChangeTask = null;
private EnchantmentApi() {} private EnchantmentApi() {}
@ -180,12 +180,12 @@ public class EnchantmentApi {
* Prepare a task to save custom recipe configuration. * Prepare a task to save custom recipe configuration.
*/ */
private static void prepareSaveTask() { 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); ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
saveChangeTask = -1; saveChangeTask = null;
}, 0L); });
} }
/** /**

View file

@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ConfigOptions; import io.delilaheve.util.ConfigOptions;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
import xyz.alexcrea.cuanvil.group.ExcludeGroup; import xyz.alexcrea.cuanvil.group.ExcludeGroup;
import xyz.alexcrea.cuanvil.group.IncludeGroup; import xyz.alexcrea.cuanvil.group.IncludeGroup;
@ -24,8 +24,8 @@ public class MaterialGroupApi {
private MaterialGroupApi(){} private MaterialGroupApi(){}
private static int saveChangeTask = -1; private static Object saveChangeTask = null;
private static int reloadChangeTask = -1; private static Object reloadChangeTask = null;
/** /**
@ -180,28 +180,28 @@ public class MaterialGroupApi {
* Prepare a task to reload every conflict. * Prepare a task to reload every conflict.
*/ */
private static void prepareSaveTask() { 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); ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true);
saveChangeTask = -1; saveChangeTask = null;
}, 0L); });
} }
/** /**
* Prepare a task to save configuration. * Prepare a task to save configuration.
*/ */
private static void prepareUpdateTask() { 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(); ConfigHolder.ITEM_GROUP_HOLDER.reload();
GroupConfigGui configGui = GroupConfigGui.getCurrentInstance(); GroupConfigGui configGui = GroupConfigGui.getCurrentInstance();
if(configGui != null) configGui.reloadValues(); if(configGui != null) configGui.reloadValues();
reloadChangeTask = -1; reloadChangeTask = null;
}, 0L); });
} }

View file

@ -2,12 +2,12 @@ package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import kotlin.Triple; import kotlin.Triple;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; 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.global.UnitRepairConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui; import xyz.alexcrea.cuanvil.gui.config.list.UnitRepairElementListGui;
@ -23,7 +23,7 @@ public class UnitRepairApi {
private UnitRepairApi(){} private UnitRepairApi(){}
private static int saveChangeTask = -1; private static Object saveChangeTask = null;
/** /**
* Write and add a custom anvil unit repair recipe. * 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. * Prepare a task to save custom unit repair recipe configuration.
*/ */
private static void prepareSaveTask() { 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); ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true);
saveChangeTask = -1; saveChangeTask = null;
}, 0L); });
} }
/** /**

View file

@ -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<String> 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;
}
}

View file

@ -12,12 +12,12 @@ public class EnchantmentRarity {
private final int itemValue; private final int itemValue;
private final int bookValue; private final int bookValue;
public EnchantmentRarity(int itemValue, int bookValue) { private EnchantmentRarity(int itemValue, int bookValue) {
this.itemValue = itemValue; this.itemValue = itemValue;
this.bookValue = bookValue; this.bookValue = bookValue;
} }
public EnchantmentRarity(int itemValue) { private EnchantmentRarity(int itemValue) {
this(itemValue, Math.max(1, itemValue / 2)); this(itemValue, Math.max(1, itemValue / 2));
} }
@ -29,4 +29,24 @@ public class EnchantmentRarity {
return itemValue; 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);
};
}
} }

View file

@ -1,7 +1,9 @@
package xyz.alexcrea.cuanvil.enchant.wrapped; package xyz.alexcrea.cuanvil.enchant.wrapped;
import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ItemUtil; import io.delilaheve.util.ItemUtil;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta; 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.EnchantmentProperties;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity; 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.Locale;
import java.util.Map;
import java.util.logging.Level;
/** /**
* Custom Anvil enchantment implementation for vanilla registered enchantment. * Custom Anvil enchantment implementation for vanilla registered enchantment.
@ -94,7 +101,7 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
try { try {
return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity(); return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();
} catch (IllegalArgumentException ignored) { } catch (IllegalArgumentException ignored) {
return EnchantmentRarity.COMMON; return findRarity(enchantment);
} }
} }
@ -102,4 +109,52 @@ public class CABukkitEnchantment extends CAEnchantmentBase {
protected Enchantment getEnchant() { protected Enchantment getEnchant() {
return this.enchantment; return this.enchantment;
} }
private static Method getAnvilCostMethod;
static {
Class<Enchantment> 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<EnchantmentTarget, String> 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;
}
}
} }

View file

@ -11,6 +11,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager; import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
import xyz.alexcrea.cuanvil.gui.config.global.*; import xyz.alexcrea.cuanvil.gui.config.global.*;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.Collections; import java.util.Collections;
@ -28,7 +29,7 @@ public class MainConfigGui extends ChestGui {
public void init(PacketManager packetManager) { public void init(PacketManager packetManager) {
Pattern pattern = new Pattern( Pattern pattern = new Pattern(
"000000000", GuiSharedConstant.EMPTY_GUI_FULL_LINE,
"012304567", "012304567",
"Q00000000" "Q00000000"
); );

View file

@ -71,7 +71,7 @@ public class SelectItemTypeGui extends AbstractAskGui {
this.pane.bindItem('V', selectGuiItem.get()); this.pane.bindItem('V', selectGuiItem.get());
// Temporary leave item // 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); this.pane.bindItem('s', temporaryLeave);

View file

@ -44,11 +44,11 @@ public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFa
@Override @Override
protected Pattern getBackgroundPattern(){ protected Pattern getBackgroundPattern(){
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"B11L1R111" "B11L1R111"
); );
} }

View file

@ -14,10 +14,12 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager; import xyz.alexcrea.cuanvil.dependency.packet.PacketManager;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui;
import xyz.alexcrea.cuanvil.gui.config.settings.EnumSettingGui;
import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
@ -26,6 +28,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List;
/** /**
* Global config to edit basic basic settings. * Global config to edit basic basic settings.
@ -59,7 +62,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
private void init() { private void init() {
Pattern pattern = new Pattern( Pattern pattern = new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
"LT0I0S0cp", "LT0IWS0cp",
"CR0U0r0hP", "CR0U0r0hP",
"B00000000" "B00000000"
); );
@ -86,6 +89,8 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
private IntSettingsGui.IntSettingFactory itemRenameCost; // r character private IntSettingsGui.IntSettingFactory itemRenameCost; // r character
private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost; // S character private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost; // S character
private EnumSettingGui.EnumSettingFactory<WorkPenaltyType> workPenaltyType; // W character
private BoolSettingsGui.BoolSettingFactory allowColorCode; // c character private BoolSettingsGui.BoolSettingFactory allowColorCode; // c character
private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character private BoolSettingsGui.BoolSettingFactory allowHexColor; // h character
@ -99,7 +104,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
*/ */
protected void prepareValues() { protected void prepareValues() {
// cap anvil cost // cap anvil cost
this.capAnvilCost = BoolSettingsGui.boolFactory("§8Cap Anvil Cost ?", this, this.capAnvilCost = new BoolSettingsGui.BoolSettingFactory("§8Cap Anvil Cost ?", this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST,
"§7All anvil cost will be capped to §aMax Anvil Cost§7 if enabled.", "§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 // repair cost item
IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE; 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, ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7Max cost the Anvil can get to.", "§7Max cost the Anvil can get to.",
@ -142,7 +147,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
// remove repair limit item // 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, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT,
"§7Whether the anvil's cost limit should be removed entirely.", "§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."); "§7However, the action will be completable if xp requirement is meet.");
// replace too expensive item // replace too expensive item
this.replaceTooExpensive = BoolSettingsGui.boolFactory("§8Replace Too Expensive ?", this, this.replaceTooExpensive = new BoolSettingsGui.BoolSettingFactory("§8Replace Too Expensive ?", this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE,
getReplaceToExpensiveLore()); getReplaceToExpensiveLore());
@ -161,7 +166,7 @@ public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
// item repair cost // item repair cost
range = ConfigOptions.REPAIR_COST_RANGE; 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, ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7XP Level amount added to the anvil when the item", "§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); 1, 5, 10, 50, 100);
// unit repair cost // 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, ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7XP Level amount added to the anvil when the item is repaired by an §eunit§7.", "§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 // item rename cost
range = ConfigOptions.ITEM_RENAME_COST_RANGE; 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, ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7XP Level amount added to the anvil when the item is renamed." "§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 // sacrifice illegal enchant cost
range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE; 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, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7XP Level amount added to the anvil when a sacrifice enchantment", "§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, ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST,
1, 5, 10, 50, 100); 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<String> 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 // Color config
// ------------- // -------------
// Allow us of color code // 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, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE,
"§7Whether players can use 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."); "§7Player may need permission to use color code if §ePlayer need permission to use color§7 is enabled.");
// Allow us of hexadecimal color // 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, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR,
"§7Whether players can use 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."); "§7Player may need permission to use color code if §ePermission Needed For Color§7 is enabled.");
// Permission needed for color // 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, ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR,
"§7Whether players should have permission to be able to use colors.", "§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 // Cost of using color
range = ConfigOptions.USE_OF_COLOR_COST_RANGE; 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, ConfigOptions.USE_OF_COLOR_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList( Arrays.asList(
"§7XP level cost when using color code or hexadecimal color using the anvil.", "§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); GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK);
pane.bindItem('S', illegalCostItem); 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 // allow color code
GuiItem allowColorCodeItem = this.allowColorCode.getItem(); GuiItem allowColorCodeItem = this.allowColorCode.getItem();
pane.bindItem('c', allowColorCodeItem); pane.bindItem('c', allowColorCodeItem);

View file

@ -40,7 +40,7 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
String key = enchant.getKey().getKey().toLowerCase(Locale.ROOT); String key = enchant.getKey().getKey().toLowerCase(Locale.ROOT);
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key); String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key);
return IntSettingsGui.intFactory(prettyKey + " Level Limit", this, return new IntSettingsGui.IntSettingFactory(prettyKey + " Level Limit", this,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Collections.singletonList( Collections.singletonList(
"§7Maximum applied level of " + prettyKey "§7Maximum applied level of " + prettyKey

View file

@ -16,7 +16,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
@ -31,24 +30,29 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu
protected PatternPane backgroundPane; 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); super(6, title, CustomAnvil.instance);
this.namePrefix = title; this.namePrefix = title;
// Back item panel // Back item panel
Pattern pattern = getBackgroundPattern(); Pattern pattern = getBackgroundPattern();
this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern); 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(){ protected Pattern getBackgroundPattern(){
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"B11L1R11C" "B11L1R11C"
); );
} }
@ -79,7 +83,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu
protected void prepareStaticValues(){ protected void prepareStaticValues(){
// Left item creation for consumer & bind // 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(); HumanEntity viewer = event.getWhoClicked();
UUID playerUUID = viewer.getUniqueId(); UUID playerUUID = viewer.getUniqueId();
int page = this.pageMap.getOrDefault(playerUUID, 0); int page = this.pageMap.getOrDefault(playerUUID, 0);
@ -94,7 +98,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu
}, CustomAnvil.instance); }, CustomAnvil.instance);
// Right item creation for consumer & bind // 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(); HumanEntity viewer = event.getWhoClicked();
UUID playerUUID = viewer.getUniqueId(); UUID playerUUID = viewer.getUniqueId();
int page = pageMap.getOrDefault(playerUUID, 0); int page = pageMap.getOrDefault(playerUUID, 0);
@ -128,7 +132,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu
protected abstract GuiItem prepareCreateNewItem(); protected abstract GuiItem prepareCreateNewItem();
protected OutlinePane createEmptyPage() { 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.align(OutlinePane.Alignment.BEGIN);
page.setOrientation(Orientable.Orientation.HORIZONTAL); page.setOrientation(Orientable.Orientation.HORIZONTAL);
@ -146,7 +150,7 @@ public abstract class ElementListConfigGui< T > extends ChestGui implements Valu
protected void addToPage(GuiItem guiItem) { protected void addToPage(GuiItem guiItem) {
// Get first available page or create one // Get first available page or create one
OutlinePane page = this.pages.get(this.pages.size() - 1); 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(); page = createEmptyPage();
this.pages.add(page); this.pages.add(page);
} }

View file

@ -7,6 +7,7 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import java.util.Arrays; import java.util.Arrays;
@ -17,7 +18,7 @@ public abstract class MappedElementListConfigGui< T, S > extends ElementListConf
protected final HashMap<T, S> elementGuiMap; protected final HashMap<T, S> elementGuiMap;
protected MappedElementListConfigGui(@NotNull String title) { protected MappedElementListConfigGui(@NotNull String title) {
super(title); super(title, MainConfigGui.getInstance());
this.elementGuiMap = new HashMap<>(); this.elementGuiMap = new HashMap<>();
} }

View file

@ -1,12 +1,14 @@
package xyz.alexcrea.cuanvil.gui.config.list; package xyz.alexcrea.cuanvil.gui.config.list;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import java.util.HashMap; import java.util.HashMap;
@ -17,12 +19,16 @@ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGu
protected HashMap<T, GuiItem> guiItemMap; protected HashMap<T, GuiItem> guiItemMap;
protected HashMap<T, S> factoryMap; protected HashMap<T, S> factoryMap;
protected SettingGuiListConfigGui(@NotNull String title) { protected SettingGuiListConfigGui(@NotNull String title, Gui parent) {
super(title); super(title, parent);
this.guiItemMap = new HashMap<>(); this.guiItemMap = new HashMap<>();
this.factoryMap = new HashMap<>(); this.factoryMap = new HashMap<>();
} }
protected SettingGuiListConfigGui(@NotNull String title) {
this(title, MainConfigGui.getInstance());
}
@Override @Override
protected GuiItem prepareCreateNewItem() { protected GuiItem prepareCreateNewItem() {
ItemStack createItem = new ItemStack(Material.PAPER); ItemStack createItem = new ItemStack(Material.PAPER);

View file

@ -112,7 +112,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
protected DoubleSettingGui.DoubleSettingFactory createFactory(String materialName) { protected DoubleSettingGui.DoubleSettingFactory createFactory(String materialName) {
String materialDisplayName = CasedStringUtil.snakeToUpperSpacedCase(materialName); String materialDisplayName = CasedStringUtil.snakeToUpperSpacedCase(materialName);
return DoubleSettingGui.doubleFactory( return new DoubleSettingGui.DoubleSettingFactory(
"§0%§8" + materialDisplayName +" Repair", "§0%§8" + materialDisplayName +" Repair",
this, this,
ConfigHolder.UNIT_REPAIR_HOLDER, ConfigHolder.UNIT_REPAIR_HOLDER,

View file

@ -77,30 +77,34 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
// Displayed item will be updated later // Displayed item will be updated later
IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE(); IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE();
this.exactCountFactory = BoolSettingsGui.boolFactory("§8Exact count ?", this, this.exactCountFactory = new BoolSettingsGui.BoolSettingFactory("§8Exact count ?", this,
ConfigHolder.DEFAULT_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG); this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG);
this.xpCostFactory = IntSettingsGui.intFactory("§8Recipe Xp Cost", this, this.xpCostFactory = new IntSettingsGui.IntSettingFactory("§8Recipe Xp Cost", this,
this.anvilRecipe +"."+AnvilCustomRecipe.XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe +"."+AnvilCustomRecipe.XP_COST_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER,
null, null,
costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_COST_CONFIG, 1, 5, 10); costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_COST_CONFIG, 1, 5, 10);
this.leftItemFactory = ItemSettingGui.itemFactory("§eRecipe Left §8Item", this, this.leftItemFactory = new ItemSettingGui.ItemSettingFactory("§eRecipe Left §8Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(),
"§7Set the left item of the custom craft", "§7Set the left item of the custom craft",
"§7\u25A0 + \u25A1 = \u25A1"); "§7\u25A0 + \u25A1 = \u25A1");
this.rightItemFactory = ItemSettingGui.itemFactory("§eRecipe Right §8Item", this, this.rightItemFactory = new ItemSettingGui.ItemSettingFactory("§eRecipe Right §8Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(),
"§7Set the right item of the custom craft", "§7Set the right item of the custom craft",
"§7\u25A1 + \u25A0 = \u25A1"); "§7\u25A1 + \u25A0 = \u25A1");
this.resultItemFactory = ItemSettingGui.itemFactory("§aRecipe Result §8Item", this, this.resultItemFactory = new ItemSettingGui.ItemSettingFactory("§aRecipe Result §8Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER, this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG,
ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(), AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(),
"§7Set the result item of the custom craft", "§7Set the result item of the custom craft",
"§7\u25A1 + \u25A1 = \u25A0"); "§7\u25A1 + \u25A1 = \u25A0");

View file

@ -95,7 +95,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
enchantGui.show(event.getWhoClicked()); enchantGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
this.minBeforeActiveSettingFactory = IntSettingsGui.intFactory( this.minBeforeActiveSettingFactory = new IntSettingsGui.IntSettingFactory(
"§8Minimum enchantment count", "§8Minimum enchantment count",
this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER, this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER,
Arrays.asList( Arrays.asList(

View file

@ -17,7 +17,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
*/ */
public abstract class AbstractSettingGui extends ChestGui implements SettingGui { public abstract class AbstractSettingGui extends ChestGui implements SettingGui {
protected static final String CLICK_LORE = "§7Click Here to change the value"; public static final String CLICK_LORE = "§7Click Here to change the value";
private PatternPane pane; private PatternPane pane;

View file

@ -161,28 +161,6 @@ public class BoolSettingsGui extends AbstractSettingGui {
return now != before; return now != before;
} }
/**
* Create a bool setting factory from setting's parameters.
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param defaultVal Default value if not found on the config.
* @param displayLore Gui display item lore.
* @return A factory for a boolean setting gui.
*/
public static BoolSettingFactory boolFactory(@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config,
@NotNull String configPath, boolean defaultVal,
String... displayLore) {
return new BoolSettingFactory(
title, parent,
config,
configPath, defaultVal,
displayLore);
}
/** /**
* A factory for a boolean setting gui that hold setting's information. * A factory for a boolean setting gui that hold setting's information.
*/ */
@ -206,7 +184,7 @@ public class BoolSettingsGui extends AbstractSettingGui {
* @param defaultVal Default value if not found on the config. * @param defaultVal Default value if not found on the config.
* @param displayLore Gui display item lore. * @param displayLore Gui display item lore.
*/ */
protected BoolSettingFactory( public BoolSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath,
boolean defaultVal, String... displayLore) { boolean defaultVal, String... displayLore) {

View file

@ -352,42 +352,6 @@ public class DoubleSettingGui extends AbstractSettingGui {
return value.toString(); return value.toString();
} }
/**
* Create a double setting factory from setting's parameters.
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param displayLore Gui display item lore.
* @param scale The scale of the decimal.
* @param asPercentage If we should display the value as a %.
* @param nullOnZero Set the value as null (deleting it) when equal to 0
* @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 a double setting gui.
*/
@NotNull
public static DoubleSettingFactory doubleFactory(@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config,
@NotNull String configPath,
@Nullable List<String> 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. * 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. * it is visually preferable to have an odd number of step.
* If step only contain 1 value, no step item should be displayed. * If step only contain 1 value, no step item should be displayed.
*/ */
protected DoubleSettingFactory( public DoubleSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull ConfigHolder config, @NotNull ConfigHolder config,
@NotNull String configPath, @NotNull String configPath,

View file

@ -15,6 +15,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.CAEnchantment; import xyz.alexcrea.cuanvil.enchant.CAEnchantment;
import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry; import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; 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.SelectEnchantmentContainer;
import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
@ -35,7 +36,7 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui<CAEnchantme
private boolean displayUnselected; private boolean displayUnselected;
public EnchantSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer) { public EnchantSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer) {
super(title); super(title, parent instanceof Gui parentGui ? parentGui : MainConfigGui.getInstance()) ;
this.enchantContainer = enchantContainer; this.enchantContainer = enchantContainer;
this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments()); this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments());
@ -52,11 +53,11 @@ public class EnchantSelectSettingGui extends SettingGuiListConfigGui<CAEnchantme
@Override @Override
protected Pattern getBackgroundPattern() { protected Pattern getBackgroundPattern() {
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"B11LbR11S" "B11LbR11S"
); );
} }

View file

@ -0,0 +1,242 @@
package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil;
import org.bukkit.Material;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
public class EnumSettingGui<T extends Enum<T> & EnumSettingGui.ConfigurableEnum> extends AbstractSettingGui {
private final EnumSettingFactory<T> 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<T> 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<InventoryClickEvent> 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<T extends Enum<T> & 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<String> getDisplayLore(T value);
/**
* @return Next value for a given enum
*/
@NotNull
public T next(@NotNull T now){
Class<T> 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();
}
}

View file

@ -17,6 +17,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; 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.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
@ -50,18 +51,22 @@ public class GroupSelectSettingGui extends AbstractSettingGui {
@Override @Override
protected Pattern getGuiPattern() { protected Pattern getGuiPattern() {
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"B1111111S" "B1111111S"
); );
} }
protected void initGroups() { protected void initGroups() {
// Add enchantment gui item // 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.setPriority(Pane.Priority.HIGH);
filledEnchant.align(OutlinePane.Alignment.BEGIN); filledEnchant.align(OutlinePane.Alignment.BEGIN);
filledEnchant.setOrientation(Orientable.Orientation.HORIZONTAL); filledEnchant.setOrientation(Orientable.Orientation.HORIZONTAL);

View file

@ -275,38 +275,11 @@ public class IntSettingsGui extends AbstractSettingGui {
return now != before; 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<String> 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. * A factory for an int setting gui that hold setting's information.
*/ */
public static class IntSettingFactory extends SettingGuiFactory { public static class IntSettingFactory extends SettingGuiFactory {
@NotNull @NotNull
String title; String title;
@NotNull @NotNull
@ -335,7 +308,7 @@ public class IntSettingsGui extends AbstractSettingGui {
* it is visually preferable to have an odd number of step. * it is visually preferable to have an odd number of step.
* If step only contain 1 value, no step item should be displayed. * If step only contain 1 value, no step item should be displayed.
*/ */
protected IntSettingFactory( public IntSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config,
@Nullable List<String> displayLore, @Nullable List<String> displayLore,

View file

@ -62,7 +62,7 @@ public class ItemSettingGui extends AbstractSettingGui {
public void prepareStaticItems(){ public void prepareStaticItems(){
prepareReturnToDefault(); prepareReturnToDefault();
GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_TERRACOTTA, this); GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this);
getPane().bindItem('s', temporaryLeave); getPane().bindItem('s', temporaryLeave);
} }
@ -163,27 +163,6 @@ public class ItemSettingGui extends AbstractSettingGui {
return !now.equals(before); 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. * 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 defaultVal Default value if not found on the config.
* @param displayLore Gui display item lore. * @param displayLore Gui display item lore.
*/ */
protected ItemSettingFactory( public ItemSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent, @NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config, @NotNull String configPath, @NotNull ConfigHolder config,
@Nullable ItemStack defaultVal, @Nullable ItemStack defaultVal,

View file

@ -57,11 +57,11 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
@Override @Override
protected Pattern getBackgroundPattern(){ protected Pattern getBackgroundPattern(){
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"BT1LAR1IS" "BT1LAR1IS"
); );
} }
@ -77,7 +77,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
super.prepareStaticValues(); super.prepareStaticValues();
// Temporary leave item // Temporary leave item
GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_TERRACOTTA, this); GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_STAINED_GLASS_PANE, this);
this.backgroundPane.bindItem('T', temporaryLeave); this.backgroundPane.bindItem('T', temporaryLeave);
// Select new mat item // Select new mat item

View file

@ -19,7 +19,9 @@ public class GuiSharedConstant {
public static final Material SECONDARY_BACKGROUND_MATERIAL = Material.BLACK_STAINED_GLASS_PANE; public static final Material SECONDARY_BACKGROUND_MATERIAL = Material.BLACK_STAINED_GLASS_PANE;
public static final GuiItem SECONDARY_BACKGROUND_ITEM = GuiGlobalItems.backgroundItem(GuiSharedConstant.SECONDARY_BACKGROUND_MATERIAL); public static final GuiItem SECONDARY_BACKGROUND_ITEM = GuiGlobalItems.backgroundItem(GuiSharedConstant.SECONDARY_BACKGROUND_MATERIAL);
public static final String UPPER_FILLER_FULL_PLANE = "111111111";
public static final String EMPTY_GUI_FULL_LINE = "000000000"; public static final String EMPTY_GUI_FULL_LINE = "000000000";
public static final String EMPTY_FILLER_FULL_LINE = "100000001";
// Temporary values, until I get something better. // Temporary values, until I get something better.
public static final boolean TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE = true; public static final boolean TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE = true;
@ -29,11 +31,11 @@ public class GuiSharedConstant {
static { static {
Pattern pattern = new Pattern( Pattern pattern = new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.UPPER_FILLER_FULL_PLANE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_FILLER_FULL_LINE,
"B11111111" "B11111111"
); );
BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern); BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern);

View file

@ -0,0 +1,61 @@
package xyz.alexcrea.cuanvil.update;
import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ConfigOptions;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
public class PluginSetDefault {
public static void reAddMissingDefault(){
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
int nbSet = 0;
nbSet+= trySetDefault(config, ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST);
nbSet+= trySetDefault(config, ConfigOptions.MAX_ANVIL_COST, ConfigOptions.DEFAULT_MAX_ANVIL_COST);
nbSet+= trySetDefault(config, ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT);
nbSet+= trySetDefault(config, ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE);
nbSet+= trySetDefault(config, ConfigOptions.ITEM_REPAIR_COST, ConfigOptions.DEFAULT_ITEM_REPAIR_COST);
nbSet+= trySetDefault(config, ConfigOptions.UNIT_REPAIR_COST, ConfigOptions.DEFAULT_UNIT_REPAIR_COST);
nbSet+= trySetDefault(config, ConfigOptions.ITEM_RENAME_COST, ConfigOptions.DEFAULT_ITEM_RENAME_COST);
nbSet+= trySetDefault(config, ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST);
nbSet+= trySetDefault(config, ConfigOptions.ALLOW_COLOR_CODE, ConfigOptions.DEFAULT_ALLOW_COLOR_CODE);
nbSet+= trySetDefault(config, ConfigOptions.ALLOW_HEXADECIMAL_COLOR, ConfigOptions.DEFAULT_ALLOW_HEXADECIMAL_COLOR);
nbSet+= trySetDefault(config, ConfigOptions.PERMISSION_NEEDED_FOR_COLOR, ConfigOptions.DEFAULT_PERMISSION_NEEDED_FOR_COLOR);
nbSet+= trySetDefault(config, ConfigOptions.USE_OF_COLOR_COST, ConfigOptions.DEFAULT_USE_OF_COLOR_COST);
nbSet+= trySetDefault(config, ConfigOptions.WORK_PENALTY_TYPE, WorkPenaltyType.DEFAULT.configName());
nbSet+= trySetDefault(config, ConfigOptions.DEFAULT_LIMIT_PATH, ConfigOptions.DEFAULT_ENCHANT_LIMIT);
if(nbSet > 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;
}
}

View file

@ -14,6 +14,7 @@ import xyz.alexcrea.cuanvil.enchant.CAEnchantmentRegistry
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
import xyz.alexcrea.cuanvil.listener.ChatEventListener import xyz.alexcrea.cuanvil.listener.ChatEventListener
import xyz.alexcrea.cuanvil.update.PluginSetDefault
import xyz.alexcrea.cuanvil.update.Update_1_21 import xyz.alexcrea.cuanvil.update.Update_1_21
import xyz.alexcrea.cuanvil.util.Metrics import xyz.alexcrea.cuanvil.util.Metrics
import java.io.File import java.io.File
@ -115,7 +116,7 @@ class CustomAnvil : JavaPlugin() {
// Load other thing later. // Load other thing later.
// It is so other dependent plugins can implement there event listener before we fire them. // 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(){ private fun loadEnchantmentSystem(){
@ -146,6 +147,9 @@ class CustomAnvil : JavaPlugin() {
MainConfigGui.getInstance().init(DependencyManager.packetManager) MainConfigGui.getInstance().init(DependencyManager.packetManager)
GuiSharedConstant.loadConstants() GuiSharedConstant.loadConstants()
// Finally, re add default we may be missing
PluginSetDefault.reAddMissingDefault()
} }
fun reloadResource( fun reloadResource(

View file

@ -3,6 +3,7 @@ package io.delilaheve.util
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import io.delilaheve.util.EnchantmentUtil.enchantmentName import io.delilaheve.util.EnchantmentUtil.enchantmentName
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.config.WorkPenaltyType
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
/** /**
@ -33,7 +34,9 @@ object ConfigOptions {
const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color" const val PERMISSION_NEEDED_FOR_COLOR = "permission_needed_for_color"
const val USE_OF_COLOR_COST = "use_of_color_cost" 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_LIMIT_ROOT = "enchant_limits"
const val ENCHANT_VALUES_ROOT = "enchant_values" const val ENCHANT_VALUES_ROOT = "enchant_values"
@ -69,7 +72,7 @@ object ConfigOptions {
const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true const val DEFAULT_PERMISSION_NEEDED_FOR_COLOR = true
const val DEFAULT_USE_OF_COLOR_COST = 0 const val DEFAULT_USE_OF_COLOR_COST = 0
private const val DEFAULT_ENCHANT_LIMIT = 5 const val DEFAULT_ENCHANT_LIMIT = 5
// Debug flag // Debug flag
private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_DEBUG_LOG = false
@ -248,6 +251,17 @@ object ConfigOptions {
?: DEFAULT_USE_OF_COLOR_COST ?: 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 * Default enchantment limit
*/ */

View file

@ -5,6 +5,7 @@ import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions
@ -15,6 +16,15 @@ class EditConfigExecutor : CommandExecutor {
sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM) sender.sendMessage(GuiGlobalActions.NO_EDIT_PERM)
return false 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 if (sender !is HumanEntity) return false
MainConfigGui.getInstance().show(sender) MainConfigGui.getInstance().show(sender)

View file

@ -1,5 +1,6 @@
package xyz.alexcrea.cuanvil.dependency package xyz.alexcrea.cuanvil.dependency
import io.delilaheve.CustomAnvil
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent 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.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.packet.PacketManager import xyz.alexcrea.cuanvil.dependency.packet.PacketManager
import xyz.alexcrea.cuanvil.dependency.packet.PacketManagerSelector 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 { object DependencyManager {
var isFolia: Boolean = false
lateinit var scheduler: TaskScheduler
lateinit var packetManager: PacketManager lateinit var packetManager: PacketManager
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
var ecoEnchantCompatibility: EcoEnchantDependency? = null var ecoEnchantCompatibility: EcoEnchantDependency? = null
@ -18,6 +24,14 @@ object DependencyManager {
fun loadDependency(){ fun loadDependency(){
val pluginManager = Bukkit.getPluginManager() 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 // Packet Manager
val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.config.getBoolean("force_protocolib", false) val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.config.getBoolean("force_protocolib", false)
packetManager = PacketManagerSelector.selectPacketManager(forceProtocolib) packetManager = PacketManagerSelector.selectPacketManager(forceProtocolib)
@ -78,4 +92,14 @@ object DependencyManager {
return bypass return bypass
} }
private fun testIsFolia(): Boolean {
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer")
return true
} catch (e: ClassNotFoundException) {
return false
}
}
} }

View file

@ -1,9 +1,9 @@
package xyz.alexcrea.cuanvil.dependency package xyz.alexcrea.cuanvil.dependency
import cz.kominekjan.disenchantment.events.ItemClickEvent import cz.kominekjan.disenchantment.events.DisenchantClickEvent
import cz.kominekjan.disenchantment.events.ItemEvent import cz.kominekjan.disenchantment.events.DisenchantEvent
import cz.kominekjan.disenchantment.events.SplitBookClickEvent import cz.kominekjan.disenchantment.events.ShatterClickEvent
import cz.kominekjan.disenchantment.events.SplitBookEvent import cz.kominekjan.disenchantment.events.ShatterEvent
import io.delilaheve.AnvilEventListener import io.delilaheve.AnvilEventListener
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
@ -19,11 +19,11 @@ class DisenchantmentDependency {
CustomAnvil.instance.logger.info("Disenchantment Detected !") CustomAnvil.instance.logger.info("Disenchantment Detected !")
} }
private lateinit var splitEvent: SplitBookEvent private lateinit var splitEvent: ShatterEvent
private lateinit var itemEvent: ItemEvent private lateinit var itemEvent: DisenchantEvent
private lateinit var splitBookClickEvent: SplitBookClickEvent private lateinit var splitBookClickEvent: ShatterClickEvent
private lateinit var itemClickEvent: ItemClickEvent private lateinit var itemClickEvent: DisenchantClickEvent
fun redirectListeners() { fun redirectListeners() {
@ -32,12 +32,12 @@ class DisenchantmentDependency {
for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) { for (registeredListener in PrepareAnvilEvent.getHandlerList().registeredListeners) {
val listener = registeredListener.listener val listener = registeredListener.listener
if(listener is SplitBookEvent){ if(listener is ShatterEvent){
this.splitEvent = listener this.splitEvent = listener
toUnregister.add(registeredListener) toUnregister.add(registeredListener)
} }
if(listener is ItemEvent){ if(listener is DisenchantEvent){
itemEvent = listener itemEvent = listener
toUnregister.add(registeredListener) toUnregister.add(registeredListener)
} }
@ -53,12 +53,12 @@ class DisenchantmentDependency {
for (registeredListener in InventoryClickEvent.getHandlerList().registeredListeners) { for (registeredListener in InventoryClickEvent.getHandlerList().registeredListeners) {
val listener = registeredListener.listener val listener = registeredListener.listener
if(listener is SplitBookClickEvent){ if(listener is ShatterClickEvent){
splitBookClickEvent = listener splitBookClickEvent = listener
toUnregister.add(registeredListener) toUnregister.add(registeredListener)
} }
if(listener is ItemClickEvent){ if(listener is DisenchantClickEvent){
itemClickEvent = listener itemClickEvent = listener
toUnregister.add(registeredListener) toUnregister.add(registeredListener)
} }

View file

@ -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)
}
}

View file

@ -1,12 +1,12 @@
package xyz.alexcrea.cuanvil.listener package xyz.alexcrea.cuanvil.listener
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Bukkit
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.player.AsyncPlayerChatEvent import org.bukkit.event.player.AsyncPlayerChatEvent
import org.bukkit.event.player.PlayerQuitEvent import org.bukkit.event.player.PlayerQuitEvent
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import java.util.* import java.util.*
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.function.Consumer import java.util.function.Consumer
@ -39,9 +39,11 @@ class ChatEventListener : Listener {
event.isCancelled = true event.isCancelled = true
// sync callback with default server thread // sync callback with default server thread
Bukkit.getScheduler().runTask(CustomAnvil.instance, Runnable { DependencyManager.scheduler.scheduleOnEntity(
CustomAnvil.instance, player,
Runnable {
eventCallback.accept(event.message) eventCallback.accept(event.message)
}) }, 0L)
} }
} }

View file

@ -38,21 +38,20 @@ object AnvilXpUtil {
anvilCost anvilCost
} }
val player = view.player
/* Because Minecraft likes to have the final say in the repair cost displayed /* 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 need to wait for the event to end before overriding it, this ensures that
* we have the final say in the process. */ * we have the final say in the process. */
CustomAnvil.instance DependencyManager.scheduler.scheduleOnEntity(
.server CustomAnvil.instance, player,
.scheduler Runnable {
.runTask(CustomAnvil.instance, Runnable {
inventory.maximumRepairCost = inventory.maximumRepairCost =
if (ConfigOptions.doRemoveCostLimit || ignoreRules) if (ConfigOptions.doRemoveCostLimit || ignoreRules)
{ Int.MAX_VALUE } { Int.MAX_VALUE }
else else
{ ConfigOptions.maxAnvilCost + 1 } { ConfigOptions.maxAnvilCost + 1 }
val player = view.player
inventory.repairCost = finalAnvilCost inventory.repairCost = finalAnvilCost
view.setProperty(REPAIR_COST, finalAnvilCost) view.setProperty(REPAIR_COST, finalAnvilCost)
player.openInventory.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 { fun calculatePenalty(left: ItemStack, right: ItemStack?, result: ItemStack, unitRepair: Boolean): Int {
// Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation // Extracted From https://minecraft.fandom.com/wiki/Anvil_mechanics#Enchantment_equation
// Calculate work penalty // Calculate work penalty
val penaltyType = ConfigOptions.workPenaltyType;
val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0 val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0
val rightPenalty = val rightPenalty =
if (right == null) { if (right == null) 0
0 else (right.itemMeta as? Repairable)?.repairCost ?: 0
} else {
(right.itemMeta as? Repairable)?.repairCost ?: 0
}
// Increase penalty on fusing or unit repair // Increase penalty on fusing or unit repair
if(right != null || unitRepair){ if(penaltyType.isPenaltyIncreasing && (right != null || unitRepair)){
result.itemMeta?.let { result.itemMeta?.let {
(it as? Repairable)?.repairCost = leftPenalty * 2 + 1 (it as? Repairable)?.repairCost = leftPenalty * 2 + 1
result.itemMeta = it result.itemMeta = it
@ -109,6 +109,8 @@ object AnvilXpUtil {
"result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}" "result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}"
) )
if(!penaltyType.isPenaltyAdditive) return 0
return leftPenalty + rightPenalty return leftPenalty + rightPenalty
} }

View file

@ -72,6 +72,18 @@ permission_needed_for_color: true
# Valid values include 0 to 1000. # Valid values include 0 to 1000.
use_of_color_cost: 0 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 # Default limit to apply to any enchants missing from enchant_limits
# #
# Valid values include 1 to 1000 # Valid values include 1 to 1000

View file

@ -1,7 +1,8 @@
main: io.delilaheve.CustomAnvil main: io.delilaheve.CustomAnvil
name: CustomAnvil name: CustomAnvil
prefix: "Custom Anvil" prefix: "Custom Anvil"
version: 1.6.0 version: 1.6.1
folia-supported: true
description: Allow to customise anvil mechanics description: Allow to customise anvil mechanics
api-version: 1.16 api-version: 1.16
load: POSTWORLD load: POSTWORLD