diff --git a/README.md b/README.md index 30cd067..f48852e 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,7 @@ It is expected to work on 1.18 to 1.20.5 minecraft servers running spigot or pap **Custom Anvil** was previously named **Unsafe Enchants+**. It was renamed because it now affects every anvil aspect and not only unsafe enchants -**Custom Anvil** is based on [Unsafe Enchants](https://github.com/DelilahEve/UnsafeEnchants) by DelilahEve. You can find it on -[GitHub](https://github.com/DelilahEve/UnsafeEnchants/releases/latest), -[Spigot](https://www.spigotmc.org/resources/unsafe-enchants.104708/) or -[CurseForge](https://www.curseforge.com/minecraft/bukkit-plugins/unsafe-enchants/files/all) +**Custom Anvil** is based on [Unsafe Enchants](https://github.com/DelilahEve/UnsafeEnchants) by DelilahEve. ### Download Locations: @@ -25,7 +22,7 @@ or [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest) - Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds) - Custom XP cost for every aspect of the anvil - Permissions to bypass level limit or enchantment restriction. -- Gui to configure the plugin in game (in alpha: can only edit 6/7 configs. next versions will focus on this feature) +- Gui to configure the plugin in game --- ### Permissions: ```yml @@ -54,10 +51,9 @@ Default configuration can be found on following links: - [custom_recipes.yml](https://github.com/alexcrea/CustomAnvil/blob/master/src/main/resources/custom_recipes.yml) --- ### Known issue: -- Custom recipe config GUI is not reloaded on reload config command. (this should not impact a lot of admin, Custom recipe config should be edited manually only in rare occasion) +There is non known issue, if you find one please report the issue. ### Planned: -- Finish the config gui - Semi manual config update on pluign or minecraft update - Check unknow registered enchantment & warn - Warn admin on unsuported minecraft version diff --git a/build.gradle.kts b/build.gradle.kts index 7fa9457..06420e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "xyz.alexcrea" -version = "1.4.3a" +version = "1.4.4" repositories { mavenCentral() diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java index 5be5529..5046bb7 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/MainConfigGui.java @@ -29,7 +29,7 @@ public class MainConfigGui extends ChestGui { private void init() { Pattern pattern = new Pattern( - "I00000000", + "000000000", "012304567", "Q00000000" ); @@ -41,6 +41,7 @@ public class MainConfigGui extends ChestGui { // Basic config item ItemStack basicConfigItemstack = new ItemStack(Material.COMMAND_BLOCK); ItemMeta basicConfigMeta = basicConfigItemstack.getItemMeta(); + assert basicConfigMeta != null; basicConfigMeta.setDisplayName("\u00A7aBasic Config Menu"); basicConfigMeta.setLore(Collections.singletonList("\u00A77Click here to open basic config menu")); @@ -52,6 +53,7 @@ public class MainConfigGui extends ChestGui { // enchant level limit item ItemStack enchantLimitItemstack = new ItemStack(Material.ENCHANTED_BOOK); ItemMeta enchantLimitMeta = enchantLimitItemstack.getItemMeta(); + assert enchantLimitMeta != null; enchantLimitMeta.setDisplayName("\u00A7aEnchantment Level Limit"); enchantLimitMeta.setLore(Collections.singletonList("\u00A77Click here to open enchantment level limit menu")); @@ -63,6 +65,7 @@ public class MainConfigGui extends ChestGui { // enchant cost item ItemStack enchantCostItemstack = new ItemStack(Material.EXPERIENCE_BOTTLE); ItemMeta enchantCostMeta = enchantCostItemstack.getItemMeta(); + assert enchantCostMeta != null; enchantCostMeta.setDisplayName("\u00A7aEnchantment Cost"); enchantCostMeta.setLore(Collections.singletonList("\u00A77Click here to open enchantment costs menu")); @@ -72,29 +75,34 @@ public class MainConfigGui extends ChestGui { pane.bindItem('3', enchantCostItem); // Enchantment Conflicts item - ItemStack EnchantConflictItemstack = new ItemStack(Material.OAK_FENCE); - ItemMeta enchantConflictMeta = EnchantConflictItemstack.getItemMeta(); + ItemStack enchantConflictItemstack = new ItemStack(Material.OAK_FENCE); + ItemMeta enchantConflictMeta = enchantConflictItemstack.getItemMeta(); + assert enchantConflictMeta != null; enchantConflictMeta.setDisplayName("\u00A7aEnchantment Conflict"); enchantConflictMeta.setLore(Collections.singletonList("\u00A77Click here to open enchantment conflict menu")); - EnchantConflictItemstack.setItemMeta(enchantConflictMeta); + enchantConflictItemstack.setItemMeta(enchantConflictMeta); - GuiItem enchantConflictItem = GuiGlobalItems.goToGuiItem(EnchantConflictItemstack, EnchantConflictGui.INSTANCE); + GuiItem enchantConflictItem = GuiGlobalItems.goToGuiItem(enchantConflictItemstack, EnchantConflictGui.INSTANCE); pane.bindItem('4', enchantConflictItem); - // WIP configuration items - ItemStack wipItemstack = new ItemStack(Material.BARRIER); - ItemMeta wipMeta = wipItemstack.getItemMeta(); - wipMeta.setDisplayName("\u00A7cWIP"); - wipItemstack.setItemMeta(wipMeta); + // Group config items + ItemStack groupItemstack = new ItemStack(Material.CHEST); + ItemMeta groupMeta = groupItemstack.getItemMeta(); + assert groupMeta != null; - GuiItem wip = new GuiItem(wipItemstack, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + groupMeta.setDisplayName("\u00A7aGroups"); + groupMeta.setLore(Collections.singletonList("\u00A77Click here to open material group menu")); + groupItemstack.setItemMeta(groupMeta); - pane.bindItem('5', wip); + GuiItem groupConfigItem = GuiGlobalItems.goToGuiItem(groupItemstack, GroupConfigGui.INSTANCE); + + pane.bindItem('5', groupConfigItem); // Unit repair item ItemStack unirRepairItemstack = new ItemStack(Material.DIAMOND); ItemMeta unitRepairMeta = unirRepairItemstack.getItemMeta(); + assert unitRepairMeta != null; unitRepairMeta.setDisplayName("\u00A7aUnit Repair"); unitRepairMeta.setLore(Collections.singletonList("\u00A77Click here to open anvil unit repair menu")); @@ -105,7 +113,8 @@ public class MainConfigGui extends ChestGui { // Custom recipe item ItemStack customRecipeItemstack = new ItemStack(Material.CRAFTING_TABLE); - ItemMeta customRecipeMeta = EnchantConflictItemstack.getItemMeta(); + ItemMeta customRecipeMeta = customRecipeItemstack.getItemMeta(); + assert customRecipeMeta != null; customRecipeMeta.setDisplayName("\u00A7aCustom recipes"); customRecipeMeta.setLore(Collections.singletonList("\u00A77Click here to open anvil custom recipe menu")); @@ -117,6 +126,8 @@ public class MainConfigGui extends ChestGui { // quit item ItemStack quitItemstack = new ItemStack(Material.BARRIER); ItemMeta quitMeta = quitItemstack.getItemMeta(); + assert quitMeta != null; + quitMeta.setDisplayName("\u00A7cQuit"); quitItemstack.setItemMeta(quitMeta); @@ -126,17 +137,6 @@ public class MainConfigGui extends ChestGui { }, CustomAnvil.instance); pane.bindItem('Q', quitItem); - // create & bind "info" item - ItemStack infoItemstack = new ItemStack(Material.PAPER); - ItemMeta infoMeta = infoItemstack.getItemMeta(); - - infoMeta.setDisplayName("\u00A7eThis is a alpha version of the gui !"); - infoMeta.setLore(Collections.singletonList("\u00A77If you have feedback or idea you can send them to the dev !")); - infoItemstack.setItemMeta(infoMeta); - - GuiItem infoItem = new GuiItem(infoItemstack, GuiGlobalActions.stayInPlace, CustomAnvil.instance); - pane.bindItem('I', infoItem); - } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectGroupContainer.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectGroupContainer.java index a8b2dba..c8668d0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectGroupContainer.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectGroupContainer.java @@ -1,7 +1,11 @@ package xyz.alexcrea.cuanvil.gui.config; import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Set; public interface SelectGroupContainer { @@ -12,4 +16,30 @@ public interface SelectGroupContainer { Set illegalGroups(); + static List getGroupLore(SelectGroupContainer container, String containerType, String groupAction){ + // Prepare group lore + ArrayList groupLore = new ArrayList<>(); + groupLore.add("\u00A77Allow you to select a list of \u00A73Groups \u00A77that this " + containerType + " should " + groupAction); + Set grouos = container.getSelectedGroups(); + if (grouos.isEmpty()) { + groupLore.add("\u00A77There is no "+groupAction+"d group for this "+containerType+"."); + } else { + groupLore.add("\u00A77List of "+groupAction+"d groups for this "+containerType+":"); + Iterator groupIterator = grouos.iterator(); + + boolean greaterThanMax = grouos.size() > 5; + int maxindex = (greaterThanMax ? 4 : grouos.size()); + for (int i = 0; i < maxindex; i++) { + // format string like "- Melee Weapons" + String formattedName = CasedStringUtil.snakeToUpperSpacedCase(groupIterator.next().getName()); + groupLore.add("\u00A77- \u00A73" + formattedName); + + } + if (greaterThanMax) { + groupLore.add("\u00A77And " + (grouos.size() - 4) + " more..."); + } + } + return groupLore; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectMaterialContainer.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectMaterialContainer.java index bd78db4..397030e 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectMaterialContainer.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/SelectMaterialContainer.java @@ -1,8 +1,9 @@ package xyz.alexcrea.cuanvil.gui.config; import org.bukkit.Material; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; -import java.util.EnumSet; +import java.util.*; public interface SelectMaterialContainer { @@ -12,4 +13,30 @@ public interface SelectMaterialContainer { EnumSet illegalMaterials(); + static List getMaterialLore(SelectMaterialContainer container, String containerType, String action){ + // Prepare material lore + ArrayList groupLore = new ArrayList<>(); + groupLore.add("\u00A77Allow you to select a list of \u00A7ematerials \u00A77that this " + containerType + " should " + action); + Set materialSet = container.getSelectedMaterials(); + if (materialSet.isEmpty()) { + groupLore.add("\u00A77There is no "+action+"d material for this "+containerType+"."); + } else { + groupLore.add("\u00A77List of "+action+"d materials for this "+containerType+":"); + Iterator materialIterator = materialSet.iterator(); + + boolean greaterThanMax = materialSet.size() > 5; + int maxindex = (greaterThanMax ? 4 : materialSet.size()); + for (int i = 0; i < maxindex; i++) { + // format string like "- Stone Sword" + String formattedName = CasedStringUtil.snakeToUpperSpacedCase(materialIterator.next().name().toLowerCase()); + groupLore.add("\u00A77- \u00A7e" + formattedName); + + } + if (greaterThanMax) { + groupLore.add("\u00A77And " + (materialSet.size() - 4) + " more..."); + } + } + return groupLore; + } + } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java index 5b962ed..d306ff1 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/ConfirmActionGui.java @@ -19,11 +19,14 @@ import java.util.logging.Level; public class ConfirmActionGui extends AbstractAskGui { public ConfirmActionGui(@NotNull String title, String actionDescription, - Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm) { + Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm, + boolean permanent) { super(3, title, backOnCancel); // Save item - this.pane.bindItem('S', new GuiItem(GuiSharedConstant.CONFIRM_ITEM, event -> { + this.pane.bindItem('S', new GuiItem( + (permanent ? GuiSharedConstant.CONFIRM_PERMANENT_ITEM : GuiSharedConstant.CONFIRM_ITEM), + event -> { event.setCancelled(true); HumanEntity player = event.getWhoClicked(); @@ -53,12 +56,19 @@ public class ConfirmActionGui extends AbstractAskGui { ItemMeta infoMeta = infoItem.getItemMeta(); infoMeta.setDisplayName("\u00A7eAre you sure ?"); - infoMeta.setLore(Arrays.asList(actionDescription.split("\n"))); + if(actionDescription != null){ + infoMeta.setLore(Arrays.asList(actionDescription.split("\n"))); + } infoItem.setItemMeta(infoMeta); pane.bindItem('I', new GuiItem(infoItem, GuiGlobalActions.stayInPlace, CustomAnvil.instance)); } + public ConfirmActionGui(@NotNull String title, String actionDescription, + Gui backOnCancel, Gui backOnConfirm, Supplier onConfirm){ + this(title, actionDescription, backOnCancel, backOnConfirm, onConfirm, true); + } + @Override protected Pattern getGuiPattern() { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java index 0ca2a38..eb15243 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/ask/SelectItemTypeGui.java @@ -16,7 +16,6 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiConsumer; -import java.util.function.Consumer; public class SelectItemTypeGui extends AbstractAskGui { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java index 684e90f..2e9bdd2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/BasicConfigGui.java @@ -18,6 +18,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import java.util.Arrays; import java.util.Collections; /** @@ -74,52 +75,84 @@ public class BasicConfigGui extends ValueUpdatableGui { protected void prepareValues() { // limit repair item this.limitRepairFactory = BoolSettingsGui.boolFactory("\u00A78Limit Repair Cost ?", this, - ConfigOptions.LIMIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_LIMIT_REPAIR); + ConfigOptions.LIMIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_LIMIT_REPAIR, + "\u00A77Whether all anvil actions cost should be capped.", + "\u00A77If true, all anvil repairs will max out at the value of \u00A7aLimit Repair Value\u00A77."); - // rename cost item + // repair cost item IntRange range = ConfigOptions.REPAIR_LIMIT_RANGE; this.repairCostFactory = IntSettingsGui.intFactory("\u00A78Repair Cost Limit", this, - ConfigOptions.LIMIT_REPAIR_VALUE, ConfigHolder.DEFAULT_CONFIG, range.getFirst(), range.getLast(), + ConfigOptions.LIMIT_REPAIR_VALUE, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77Value to limit repair costs to when \u00A7aLimit Repair Value\u00A77 is true.", + "\u00A77Valid values include \u00A7e1 \u00A77to \u00A7e39\u00A77: " + + "vanilla would display \u00A7e40+\u00A77 as \u00A7ctoo expensive\u00A77." + ), + range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_LIMIT_REPAIR_VALUE, 1, 5, 10); - // rename cost not needed + // repair cost not needed ItemStack item = new ItemStack(Material.BARRIER); ItemMeta meta = item.getItemMeta(); + assert meta != null; - meta.setDisplayName("\u00A7cRepair Cost Value"); - meta.setLore(Collections.singletonList("\u00A77Please, enable repair cost limit for this variable to be editable.")); + meta.setDisplayName("\u00A7cLimit Repair Value"); + meta.setLore(Collections.singletonList("\u00A77This config need \u00A7cLimit Repair Cost\u00A77 enabled.")); item.setItemMeta(meta); this.notNeededLimitValueItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); // remove repair limit item this.removeRepairLimit = BoolSettingsGui.boolFactory("\u00A78Remove Repair Limit ?", this, - ConfigOptions.REMOVE_REPAIR_LIMIT, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_REMOVE_LIMIT); + ConfigOptions.REMOVE_REPAIR_LIMIT, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_REMOVE_LIMIT, + "\u00A77Whether the anvil's repair limit should be removed entirely.", + "\u00A77The anvil will still visually display \u00A7ctoo expensive\u00A77.", + "\u00A77However the action will be completable."); // item repair cost range = ConfigOptions.REPAIR_COST_RANGE; this.itemRepairCost = IntSettingsGui.intFactory("\u00A78Item Repair Cost", this, - ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, range.getFirst(), range.getLast(), + ConfigOptions.ITEM_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP Level amount added to the anvil when the item", + "\u00A77is repaired by another item of the same type." + ), + range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_REPAIR_COST, 1, 5, 10, 50, 100); // unit repair cost this.unitRepairCost = IntSettingsGui.intFactory("\u00A78Unit Repair Cost", this, - ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, range.getFirst(), range.getLast(), + ConfigOptions.UNIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP Level amount added to the anvil when the item is repaired by an \u00A7eunit\u00A77.", + "\u00A77For example: a Diamond on a Diamond Sword.", + "\u00A77What's considered unit for what can be edited on the unit repair configuration." + ), + range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_UNIT_REPAIR_COST, 1, 5, 10, 50, 100); // item rename cost range = ConfigOptions.ITEM_RENAME_COST_RANGE; this.itemRenameCost = IntSettingsGui.intFactory("\u00A78Rename Cost", this, - ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, range.getFirst(), range.getLast(), + ConfigOptions.ITEM_RENAME_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP Level amount added to the anvil when the item is renamed." + ), + range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_ITEM_RENAME_COST, 1, 5, 10, 50, 100); // sacrifice illegal enchant cost range = ConfigOptions.SACRIFICE_ILLEGAL_COST_RANGE; this.sacrificeIllegalEnchantCost = IntSettingsGui.intFactory("\u00A78Sacrifice Illegal Enchant Cost", this, - ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, range.getFirst(), range.getLast(), + ConfigOptions.SACRIFICE_ILLEGAL_COST, ConfigHolder.DEFAULT_CONFIG, + Arrays.asList( + "\u00A77XP Level amount added to the anvil when a sacrifice enchantment", + "\u00A77conflict With one of the left item enchantment" + ), + range.getFirst(), range.getLast(), ConfigOptions.DEFAULT_SACRIFICE_ILLEGAL_COST, 1, 5, 10, 50, 100); @@ -128,36 +161,36 @@ public class BasicConfigGui extends ValueUpdatableGui { @Override public void updateGuiValues() { // limit repair item - GuiItem limitRepairItem = GuiGlobalItems.boolSettingGuiItem(this.limitRepairFactory); + GuiItem limitRepairItem = this.limitRepairFactory.getItem(); pane.bindItem('1', limitRepairItem); // rename cost item GuiItem limitRepairValueItem; if (this.limitRepairFactory.getConfiguredValue()) { - limitRepairValueItem = GuiGlobalItems.intSettingGuiItem(this.repairCostFactory, Material.EXPERIENCE_BOTTLE); + limitRepairValueItem = this.repairCostFactory.getItem(Material.EXPERIENCE_BOTTLE); } else { limitRepairValueItem = this.notNeededLimitValueItem; } pane.bindItem('2', limitRepairValueItem); // remove repair limit item - GuiItem removeRepairLimitItem = GuiGlobalItems.boolSettingGuiItem(this.removeRepairLimit); + GuiItem removeRepairLimitItem = this.removeRepairLimit.getItem(); pane.bindItem('3', removeRepairLimitItem); // item repair cost - GuiItem itemRepairCostItem = GuiGlobalItems.intSettingGuiItem(this.itemRepairCost, Material.ANVIL); + GuiItem itemRepairCostItem = this.itemRepairCost.getItem(Material.ANVIL); pane.bindItem('4', itemRepairCostItem); // unit repair cost - GuiItem unitRepairCostItem = GuiGlobalItems.intSettingGuiItem(this.unitRepairCost, Material.DIAMOND); + GuiItem unitRepairCostItem = this.unitRepairCost.getItem(Material.DIAMOND); pane.bindItem('5', unitRepairCostItem); // item rename cost - GuiItem itemRenameCost = GuiGlobalItems.intSettingGuiItem(this.itemRenameCost, Material.NAME_TAG); + GuiItem itemRenameCost = this.itemRenameCost.getItem(Material.NAME_TAG); pane.bindItem('6', itemRenameCost); // sacrifice illegal enchant cost - GuiItem illegalCostItem = GuiGlobalItems.intSettingGuiItem(this.sacrificeIllegalEnchantCost, Material.ENCHANTED_BOOK); + GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK); pane.bindItem('7', illegalCostItem); update(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java index 6aeb596..d0c0ec2 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java @@ -41,6 +41,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui lore = new ArrayList<>(); + lore.add("\u00A77Item Cost: \u00A7e" + itemCost); + lore.add("\u00A77Book Cost: \u00A7e" + bookCost); + + List displayLore = factory.getDisplayLore(); + if(!displayLore.isEmpty()){ + lore.add(""); + lore.addAll(displayLore); + } // Edit name and lore itemMeta.setDisplayName(itemName); - itemMeta.setLore(Arrays.asList( - "\u00A77Item Cost: " + itemCost, - "\u00A77Book Cost: " + bookCost)); + itemMeta.setLore(lore); item.setItemMeta(itemMeta); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java index 999f2a7..36f3450 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/EnchantLimitConfigGui.java @@ -5,9 +5,9 @@ import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; -import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import java.util.Collections; import java.util.Locale; /** @@ -37,14 +37,18 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui { + + public final static GroupConfigGui INSTANCE = new GroupConfigGui(); + + static { + INSTANCE.init(); + } + + public GroupConfigGui() { + super("Group Config"); + } + + @Override + protected ItemStack createItemForGeneric(IncludeGroup group) { + ItemStack item = new ItemStack(group.getRepresentativeMaterial()); + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.addItemFlags(ItemFlag.values()); + meta.setDisplayName("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(group.getName())+ " \u00A7fGroup"); + meta.setLore(Arrays.asList( + "\u00A77Number of selected groups : " + group.getGroups().size(), + "\u00A77Number of included material : " + group.getNonGroupInheritedMaterials().size(), + "", + "\u00A77Total number of included material "+group.getMaterials().size())); + + item.setItemMeta(meta); + return item; + } + + @Override + protected List getEveryDisplayableInstanceOfGeneric() { + ArrayList includeGroups = new ArrayList<>(); + + for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { + if(group instanceof IncludeGroup){ + includeGroups.add((IncludeGroup) group); + } + } + return includeGroups; + } + + @Override + protected GroupConfigSubSettingGui newInstanceOfGui(IncludeGroup group, GuiItem item) { + return new GroupConfigSubSettingGui(this, group, item); + } + + @Override + protected String genericDisplayedName() { + return "material group"; + } + + @Override + protected IncludeGroup createAndSaveNewEmptyGeneric(String name) { + ItemGroupManager manager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + if(manager.getGroupMap().containsKey(name)) return null; + + ConfigurationSection config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig(); + config.set(name+"."+ItemGroupManager.GROUP_TYPE_PATH, GroupType.INCLUDE.getGroupID()); + + return (IncludeGroup) manager.createGroup(config, name); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java index d872def..6bd4c96 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/UnitRepairConfigGui.java @@ -48,6 +48,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui extends ValueUpdatableGui { this.namePrefix = title; // Back item panel - Pattern pattern = new Pattern( + Pattern pattern = getBackgroundPattern(); + this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern); + GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.INSTANCE); + + } + + protected Pattern getBackgroundPattern(){ + return new Pattern( GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE, @@ -42,12 +49,8 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui { GuiSharedConstant.EMPTY_GUI_FULL_LINE, "B11L1R11C" ); - this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern); - GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.INSTANCE); - } - protected OutlinePane firstPage; protected ArrayList pages; protected HashMap pageMap; @@ -103,7 +106,10 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui { viewer.setItemOnCursor(cursor); }, CustomAnvil.instance); - this.backgroundPane.bindItem('C', prepareCreateNewItem()); + GuiItem createNew = prepareCreateNewItem(); + if(createNew != null){ + this.backgroundPane.bindItem('C', createNew); + } } protected void reloadValues(){ this.firstPage.clear(); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java index 9f5c2a5..3f2b7f5 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedElementListConfigGui.java @@ -27,6 +27,7 @@ public abstract class MappedElementListConfigGui< T, S > extends ElementListConf // Create new conflict item ItemStack createItem = new ItemStack(Material.PAPER); ItemMeta createMeta = createItem.getItemMeta(); + assert createMeta != null; createMeta.setDisplayName("\u00A7aCreate new "+genericDisplayedName()); createMeta.setLore(Arrays.asList( diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java index 8b81fff..5438600 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/MappedGuiListConfigGui.java @@ -4,6 +4,7 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem; import io.delilaheve.CustomAnvil; import org.bukkit.entity.HumanEntity; import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import java.util.Locale; @@ -81,6 +82,10 @@ public abstract class MappedGuiListConfigGui< T, S extends ElementMappedToListGu } T generic = createAndSaveNewEmptyGeneric(message); + if(generic == null) {// we don't know what to do. so we back up by opening this gui. + this.show(player); + return; + } updateValueForGeneric(generic, true); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java index 328743c..231cf67 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/SettingGuiListConfigGui.java @@ -27,6 +27,7 @@ public abstract class SettingGuiListConfigGui< T, S extends AbstractSettingGui.S protected GuiItem prepareCreateNewItem() { ItemStack createItem = new ItemStack(Material.PAPER); ItemMeta createMeta = createItem.getItemMeta(); + assert createMeta != null; createMeta.setDisplayName(createItemName()); createMeta.setLore(getCreateItemLore()); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java index fdbc7d8..b4a1d6d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/UnitRepairElementListGui.java @@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.config.ask.SelectItemTypeGui; import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui; +import xyz.alexcrea.cuanvil.gui.config.list.elements.ElementMappedToListGui; import xyz.alexcrea.cuanvil.gui.config.settings.DoubleSettingGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; @@ -26,19 +27,19 @@ import java.util.function.Consumer; public class UnitRepairElementListGui extends SettingGuiListConfigGui implements ElementMappedToListGui { private final GuiItem parentItem; - private final Material material; + private final Material parentMaterial; private final UnitRepairConfigGui parentGui; private final String materialName; private boolean shouldWork = true; - public UnitRepairElementListGui(@NotNull Material material, + public UnitRepairElementListGui(@NotNull Material parentMaterial, @NotNull UnitRepairConfigGui parentGui, @NotNull GuiItem parentItem) { - super("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()) + " \u00A7rUnit repair"); + super("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()) + " \u00A7rUnit repair"); this.parentItem = parentItem; - this.material = material; + this.parentMaterial = parentMaterial; this.parentGui = parentGui; - this.materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()); + this.materialName = CasedStringUtil.snakeToUpperSpacedCase(parentMaterial.name().toLowerCase()); GuiGlobalItems.addBackItem(this.backgroundPane, parentGui); } @@ -74,7 +75,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui { event.setCancelled(true); EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui( @@ -101,6 +98,10 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl this.minBeforeActiveSettingFactory = IntSettingsGui.intFactory( "\u00A78Minimum enchantment count", this, this.enchantConflict + ".maxEnchantmentBeforeConflict", ConfigHolder.CONFLICT_HOLDER, + Arrays.asList( + "\u00A77Minimum enchantment count set to X mean only X enchantment can be put", + "\u00A77on an item before the conflict is active." + ), 0, 255, 0, 1 ); @@ -184,31 +185,12 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl } // Prepare group lore - ArrayList groupLore = new ArrayList<>(); - groupLore.add("\u00A77Allow you to select a list of \u00A73Groups \u00A77that this conflict should include"); - Set grouos = getSelectedGroups(); - if (grouos.isEmpty()) { - groupLore.add("\u00A77There is no excluded groups for this conflict."); - } else { - groupLore.add("\u00A77List of excluded groups for this conflict:"); - Iterator groupIterator = grouos.iterator(); - - boolean greaterThanMax = grouos.size() > 5; - int maxindex = (greaterThanMax ? 4 : grouos.size()); - for (int i = 0; i < maxindex; i++) { - // format string like "- Melee Weapons" - String formattedName = CasedStringUtil.snakeToUpperSpacedCase(groupIterator.next().getName()); - groupLore.add("\u00A77- \u00A73" + formattedName); - - } - if (greaterThanMax) { - groupLore.add("\u00A77And " + (grouos.size() - 4) + " more..."); - } - } + List groupLore = SelectGroupContainer.getGroupLore(this, "conflict", "exclude"); // Configure enchant setting item ItemStack enchantItem = this.enchantSettingItem.getItem(); ItemMeta enchantMeta = enchantItem.getItemMeta(); + assert enchantMeta != null; enchantMeta.setDisplayName("\u00A7aSelect included \u00A75Enchantments \u00A7aSettings"); enchantMeta.setLore(enchantLore); @@ -220,16 +202,17 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl // Configure group setting item ItemStack groupItem = this.groupSettingItem.getItem(); ItemMeta groupMeta = groupItem.getItemMeta(); + assert groupMeta != null; - groupMeta.setDisplayName("\u00A7aSelect excluded \u00A73Groups \u00A7aSettings"); + groupMeta.setDisplayName("\u00A7aSelect Excluded \u00A73Groups \u00A7aSettings"); groupMeta.setLore(groupLore); groupItem.setItemMeta(groupMeta); this.groupSettingItem.setItem(groupItem); // Just in case - - this.pane.bindItem('M', GuiGlobalItems.intSettingGuiItem(this.minBeforeActiveSettingFactory, Material.COMMAND_BLOCK)); + this.pane.bindItem('M', this.minBeforeActiveSettingFactory.getItem(Material.COMMAND_BLOCK, + "Minimum Enchantment Count")); update(); } @@ -288,7 +271,6 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl CustomAnvil.instance.getLogger().log(Level.WARNING, "An error occurred while updating enchants for " + this.enchantConflict, e); } - // Save file configuration to disk if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { return ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java new file mode 100644 index 0000000..29d412b --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/GroupConfigSubSettingGui.java @@ -0,0 +1,401 @@ +package xyz.alexcrea.cuanvil.gui.config.list.elements; + +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +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.entity.HumanEntity; +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.group.*; +import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; +import xyz.alexcrea.cuanvil.gui.config.SelectMaterialContainer; +import xyz.alexcrea.cuanvil.gui.config.ask.ConfirmActionGui; +import xyz.alexcrea.cuanvil.gui.config.global.GroupConfigGui; +import xyz.alexcrea.cuanvil.gui.config.settings.GroupSelectSettingGui; +import xyz.alexcrea.cuanvil.gui.config.settings.MaterialSelectSettingGui; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; +import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implements SelectGroupContainer, SelectMaterialContainer { + + private final GroupConfigGui parent; + private final IncludeGroup group; + private final PatternPane pane; + private boolean usable = true; + + public GroupConfigSubSettingGui( + @NotNull GroupConfigGui parent, + @NotNull IncludeGroup group, + @NotNull GuiItem item) { + super(item, 3, + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " Config"); + this.parent = parent; + this.group = group; + + Pattern pattern = new Pattern( + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + "00102000D", + "B00000000" + ); + this.pane = new PatternPane(0, 0, 9, 3, pattern); + addPane(this.pane); + + prepareStaticValues(); + } + + private GuiItem materialSelection; + private GuiItem groupSelection; + private void prepareStaticValues() { + GuiGlobalItems.addBackItem(this.pane, this.parent); + GuiGlobalItems.addBackgroundItem(this.pane); + + // Delete item + ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA); + ItemMeta deleteMeta = deleteItem.getItemMeta(); + + deleteMeta.setDisplayName("\u00A74DELETE GROUP"); + deleteMeta.setLore(Collections.singletonList("\u00A7cCaution with this button !")); + + deleteItem.setItemMeta(deleteMeta); + this.pane.bindItem('D', new GuiItem(deleteItem, openGuiAndCheckAction(), CustomAnvil.instance)); + + // Displayed item will be updated later + this.materialSelection = new GuiItem(new ItemStack(Material.DIAMOND_SWORD), (event) -> { + event.setCancelled(true); + + MaterialSelectSettingGui selectGui = new MaterialSelectSettingGui(this, + CasedStringUtil.snakeToUpperSpacedCase(group.getName()) + " Materials" + , this); + selectGui.show(event.getWhoClicked()); + + }, CustomAnvil.instance); + + this.groupSelection = new GuiItem(new ItemStack(Material.CHEST), (event) -> { + event.setCancelled(true); + GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( + CasedStringUtil.snakeToUpperSpacedCase(this.group.getName()) + " Groups", + this, this, 0); + enchantGui.show(event.getWhoClicked()); + }, CustomAnvil.instance); + + this.pane.bindItem('1', this.materialSelection); + this.pane.bindItem('2', this.groupSelection); + } + + private @NotNull Consumer openGuiAndCheckAction() { + ConfirmActionGui deleteGui = createDeleteGui(); + return event -> { + event.setCancelled(true); + HumanEntity player = event.getWhoClicked(); + // Do not allow to open inventory if player do not have edit configuration permission + if (!player.hasPermission(CustomAnvil.editConfigPermission)) { + player.closeInventory(); + player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + return; + } + // test if group is used & cancel & warn user if so + if(testAndWarnIfUsed(player)) return; + + deleteGui.show(player); + }; + } + + private @NotNull ConfirmActionGui createDeleteGui() { + Supplier deleteSupplier = () -> { + // test if group is used & cancel if so + if(!getUsedLocations(this.group).isEmpty()) return false; + + ItemGroupManager manager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + + // Remove from manager + manager.getGroupMap().remove(this.group.getName()); + + // Remove from parent + this.parent.removeGeneric(this.group); + + // Remove self + cleanAndBeUnusable(); + + // Update config file storage + ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig().set(this.group.getName(), null); + + // Save + boolean success = true; + if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { + success = ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + } + + return success; + }; + + return new ConfirmActionGui("\u00A7cDelete \u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.toString()) + "\u00A7c?", + "\u00A77Confirm that you want to delete this group.", + this, this.parent, deleteSupplier + ); + } + + public boolean testAndWarnIfUsed(HumanEntity player){ + List usedLoc = getUsedLocations(this.group); + if(usedLoc.isEmpty()){ + return false; + } + StringBuilder stb = new StringBuilder("\u00A7cCan't delete group " +this.group.getName()+ + "\n\u00A7eUsed by:"); + int maxIndex = usedLoc.size(); + int nbMore = 0; + if(maxIndex > 10){ + nbMore = maxIndex - 9; + maxIndex = 9; + } + for (int i = 0; i < maxIndex; i++) { + stb.append("\n\u00A7r-\u00A7e ").append(usedLoc.get(i)); + } + if(nbMore > 0){ + stb.append("\u00A7cAnd ").append(nbMore).append(" More..."); + } + + player.sendMessage(stb.toString()); + return true; + } + + // return a string containing every instance of where this group is used + public static List getUsedLocations(AbstractMaterialGroup group){ + ArrayList usageList = new ArrayList<>(); + + // Test used by another group + ItemGroupManager groupManager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager(); + for (AbstractMaterialGroup otherGroup : groupManager.getGroupMap().values()) { + if(otherGroup.getGroups().contains(group)) { + usageList.add("group " + otherGroup.getName()); + } + } + + // Test if used for conflict + EnchantConflictManager conflictManager = ConfigHolder.CONFLICT_HOLDER.getConflictManager(); + for (EnchantConflictGroup conflict : conflictManager.getConflictList()) { + if(conflict.getCantConflictGroup().getGroups().contains(group)) { + usageList.add("conflict " + conflict); + } + } + + return usageList; + } + + @Override + public void updateGuiValues() { + if(!this.usable) return; + // Parent should call updateLocal with this call + this.parent.updateValueForGeneric(this.group, true); + + } + + @Override + public void updateLocal() { + if(!this.usable) return; + // Prepare material lore + List matLore = SelectMaterialContainer.getMaterialLore(this, "group", "include"); + + // Prepare group lore + List groupLore = SelectGroupContainer.getGroupLore(this, "group", "include"); + + // Configure included material setting item + ItemStack matSelectItem = this.materialSelection.getItem(); + ItemMeta matSelectMeta = matSelectItem.getItemMeta(); + + matSelectMeta.setDisplayName("\u00A7aSelect included \u00A7eMaterials \u00A7aSettings"); + matSelectMeta.setLore(matLore); + matSelectMeta.addItemFlags(ItemFlag.values()); + + matSelectItem.setItemMeta(matSelectMeta); + + this.materialSelection.setItem(matSelectItem); // Just in case + + // Configure enchant setting item + ItemStack groupSelectItem = this.groupSelection.getItem(); + ItemMeta groupSelectMeta = groupSelectItem.getItemMeta(); + + groupSelectMeta.setDisplayName("\u00A7aSelect included \u00A73Groups \u00A7aSettings"); + groupSelectMeta.setLore(groupLore); + + groupSelectItem.setItemMeta(groupSelectMeta); + + this.groupSelection.setItem(groupSelectItem); // Just in case + } + + @Override + public void cleanAndBeUnusable() { + this.usable = false; + this.pane.bindItem('1', GuiGlobalItems.backgroundItem()); + this.pane.bindItem('2', GuiGlobalItems.backgroundItem()); + this.pane.bindItem('D', GuiGlobalItems.backgroundItem()); + + } + + @Override + public void show(@NotNull HumanEntity player) { + if(!this.usable) { + this.parent.show(player); + return; + } + super.show(player); + } + + // ---------------------------- + // SelectGroupContainer related methods + // ---------------------------- + + @Override + public Set getSelectedGroups() { + return this.group.getGroups(); + } + + @Override + public boolean setSelectedGroups(Set groups) { + // update group and referencing groups + updateGroup(this.group, groups); + + // Save file configuration to disk + if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { + return ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + } + + return true; + } + + private void updateGroup(@NotNull AbstractMaterialGroup group, Set groups){ + // Set live configuration + group.setGroups(groups); + + // Write to file configuration + groups = group.getGroups(); // Maybe some group may have been rejected + String[] groupNames = new String[groups.size()]; + int index = 0; + for (AbstractMaterialGroup otherGroup : groups) { + groupNames[index++] = otherGroup.getName(); + } + + ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(group.getName()+"."+ItemGroupManager.GROUP_LIST_PATH, groupNames); + + // Try to update referencing group. kind of expensive operation in some case. + updateDirectReferencingGroups(group); + + // We assume a backup & save call will be done soon after + } + + @Override + public Set illegalGroups() { + Set illegal = new HashSet<>(); + + for (AbstractMaterialGroup otherGroup : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { + if(otherGroup.isReferencing(this.group)){ + illegal.add(otherGroup); + } + } + illegal.add(this.group); + + return illegal; + } + + // ---------------------------- + // End of SelectGroupContainer related methods + // ---------------------------- + // SelectGroupContainer related methods + // ---------------------------- + + @Override + public EnumSet getSelectedMaterials() { + return this.group.getNonGroupInheritedMaterials(); + } + + @Override + public boolean setSelectedMaterials(EnumSet materials) { + this.group.setNonGroupInheritedMaterials(materials); + + // Write to file configuration + String[] groupNames = new String[materials.size()]; + int index = 0; + for (Material otherGroup : materials) { + groupNames[index++] = otherGroup.name().toLowerCase(); + } + + ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames); + + // update referencing groups + updateDirectReferencingGroups(this.group); + + // Save file configuration to disk + if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { + return ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + } + return true; + } + + @Override + public EnumSet illegalMaterials() { + return EnumSet.of(Material.AIR); + } + + // ---------------------------- + // End of SelectGroupContainer related methods + // ---------------------------- + + private void updateDirectReferencingGroups(AbstractMaterialGroup referenceTo){ + Collection everyStoredGroups = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values(); + List everyConflicts = ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList(); + + HashSet toUpdate = new HashSet<>(); + HashSet updateFuture = new HashSet<>(); + HashSet conflictGroupPlanned = new HashSet<>(); + + updateFuture.add(referenceTo); + while (!updateFuture.isEmpty()){ + HashSet temp = updateFuture; + updateFuture = toUpdate; + updateFuture.clear(); + toUpdate = temp; + + for (AbstractMaterialGroup testGroup : toUpdate) { + // Update other stored group + for (AbstractMaterialGroup otherGroup : everyStoredGroups) { + if(otherGroup.getGroups().contains(testGroup)){ + otherGroup.updateMaterials(); + toUpdate.add(otherGroup); + } + } + + // plan update for conflict groups + for (EnchantConflictGroup everyConflict : everyConflicts) { + AbstractMaterialGroup conflictGroup = everyConflict.getCantConflictGroup(); + if(conflictGroup.getGroups().contains(testGroup)){ + conflictGroupPlanned.add(conflictGroup); + } + } + + // Update parent & local by extension + if(testGroup instanceof IncludeGroup){ + this.parent.updateValueForGeneric((IncludeGroup) testGroup, false); + } + } + } + this.parent.update(); + + // Update conflict group + for (AbstractMaterialGroup conflictGroup : conflictGroupPlanned) { + conflictGroup.updateMaterials(); + } + + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java index 08b4a2f..68273bc 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/list/elements/MappedToListSubSettingGui.java @@ -5,7 +5,6 @@ import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import io.delilaheve.CustomAnvil; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; -import xyz.alexcrea.cuanvil.gui.config.list.ElementMappedToListGui; public abstract class MappedToListSubSettingGui extends ValueUpdatableGui implements ElementMappedToListGui { diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java index 0248c9d..d952f0c 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/AbstractSettingGui.java @@ -12,15 +12,12 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; -import java.util.Collections; -import java.util.List; - /** * An instance gui used to edit a setting. */ public abstract class AbstractSettingGui extends ChestGui { - protected final static List CLICK_LORE = Collections.singletonList("\u00A77Click Here to change the value"); + protected final static String CLICK_LORE = "\u00A77Click Here to change the value"; private PatternPane pane; @@ -119,7 +116,9 @@ public abstract class AbstractSettingGui extends ChestGui { * It is better to keep a factory that hold setting data than find what parameters to use every time. */ public abstract static class SettingGuiFactory { + @NotNull protected String configPath; + @NotNull protected ConfigHolder config; /** @@ -128,7 +127,7 @@ public abstract class AbstractSettingGui extends ChestGui { * @param configPath Configuration path of this setting. * @param config Configuration holder of this setting. */ - protected SettingGuiFactory(String configPath, ConfigHolder config) { + protected SettingGuiFactory(@NotNull String configPath, @NotNull ConfigHolder config) { this.configPath = configPath; this.config = config; } @@ -136,6 +135,7 @@ public abstract class AbstractSettingGui extends ChestGui { /** * @return Configuration path of this setting. */ + @NotNull public String getConfigPath() { return configPath; } @@ -143,6 +143,7 @@ public abstract class AbstractSettingGui extends ChestGui { /** * @return Configuration holder of this setting. */ + @NotNull public ConfigHolder getConfigHolder() { return config; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java index f65d5cf..38c3c09 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/BoolSettingsGui.java @@ -13,9 +13,13 @@ 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 xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.function.Consumer; /** @@ -59,11 +63,21 @@ public class BoolSettingsGui extends AbstractSettingGui { * Prepare "return to default value" gui item. */ protected void prepareReturnToDefault() { + // Prepare default Value text + String defaultValueLore; + if(holder.defaultVal){ + defaultValueLore = "\u00A7aYes \u00A77Is the default value"; + }else{ + defaultValueLore = "\u00A7cNo \u00A77Is the default value"; + } + + // Create reset to default item ItemStack item = new ItemStack(Material.COMMAND_BLOCK); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7eReset to default value"); - meta.setLore(Collections.singletonList("\u00A77Default value is: " + holder.defaultVal)); + meta.setLore(Collections.singletonList(defaultValueLore)); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { event.setCancelled(true); @@ -83,17 +97,27 @@ public class BoolSettingsGui extends AbstractSettingGui { String displayedName; Material displayedMat; if (now) { - displayedName = "\u00A7aTrue"; + displayedName = "\u00A7aYes"; displayedMat = Material.GREEN_TERRACOTTA; } else { - displayedName = "\u00A7cFalse"; + displayedName = "\u00A7cNo"; displayedMat = Material.RED_TERRACOTTA; } + // create & set Value item + ArrayList valueLore = new ArrayList<>(); + if(!holder.displayLore.isEmpty()){ + valueLore.addAll(holder.displayLore); + valueLore.add(""); + } + valueLore.add(AbstractSettingGui.CLICK_LORE); + ItemStack valueItemStack = new ItemStack(displayedMat); ItemMeta valueMeta = valueItemStack.getItemMeta(); + assert valueMeta != null; + valueMeta.setDisplayName(displayedName); - valueMeta.setLore(AbstractSettingGui.CLICK_LORE); + valueMeta.setLore(valueLore); valueItemStack.setItemMeta(valueMeta); GuiItem resultItem = new GuiItem(valueItemStack, inverseNowConsumer(), CustomAnvil.instance); @@ -141,20 +165,22 @@ public class BoolSettingsGui extends AbstractSettingGui { /** * 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 configPath Configuration path of this setting. - * @param config Configuration holder of this setting. - * @param defaultVal Default value if not found on the config. + * @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 a boolean setting gui. */ - public static BoolSettingFactory boolFactory(@NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, - boolean defaultVal) { + public static BoolSettingFactory boolFactory(@NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + boolean defaultVal, + String... displayLore) { return new BoolSettingFactory( title, parent, configPath, config, - defaultVal); + defaultVal, displayLore); } /** @@ -163,27 +189,33 @@ public class BoolSettingsGui extends AbstractSettingGui { public static class BoolSettingFactory extends SettingGuiFactory { @NotNull String title; + @NotNull ValueUpdatableGui parent; boolean defaultVal; + @NotNull + List displayLore; + /** * Constructor for a boolean setting 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. - * @param defaultVal Default value if not found on the config. + * @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. */ protected BoolSettingFactory( - @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, - boolean defaultVal) { + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + boolean defaultVal, String... displayLore) { super(configPath, config); this.title = title; this.parent = parent; this.defaultVal = defaultVal; + this.displayLore = Arrays.asList(displayLore); } /** @@ -209,6 +241,48 @@ public class BoolSettingsGui extends AbstractSettingGui { return new BoolSettingsGui(this, now); } + /** + * Create a new Boolean setting GuiItem. + * This item will create and open a boolean setting GUI from the factory. + * The item will have its value written in the lore part of the item. + * + * @param name Name of the item. + * @return A formatted GuiItem that will create and open a GUI for the boolean setting. + */ + public GuiItem getItem(String name){ + // Get item properties + boolean value = getConfiguredValue(); + + Material itemMat; + StringBuilder itemName = new StringBuilder("\u00A7e"); + String finalValue; + if (value) { + itemMat = Material.GREEN_TERRACOTTA; + finalValue = "\u00A7aYes"; + } else { + itemMat = Material.RED_TERRACOTTA; + finalValue = "\u00A7cNo"; + } + itemName.append(name); + + return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, finalValue, this.displayLore, false); + } + + /** + * Create a new boolean setting GuiItem. + * This item will create and open a boolean setting GUI from the factory. + * The item will have its value written in the lore part of the item. + * Item's name will be the factory set title. + * + * @return A formatted GuiItem that will create and open a GUI for the boolean setting. + */ + public GuiItem getItem(){ + // Get item properties + String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); + + return getItem(CasedStringUtil.detectToUpperSpacedCase(configPath)); + } + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java index 772f473..1e28a9b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/DoubleSettingGui.java @@ -10,6 +10,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; 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.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; @@ -20,6 +21,7 @@ import xyz.alexcrea.cuanvil.util.MetricsUtil; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -64,6 +66,7 @@ public class DoubleSettingGui extends AbstractSettingGui { private static final ItemStack DELETE_ITEM_STACK = new ItemStack(Material.RED_TERRACOTTA); static { ItemMeta meta = DELETE_ITEM_STACK.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7cDisable item being repaired ?"); meta.setLore(Arrays.asList("\u00A77Confirm disabling unit repair for this item..", @@ -116,9 +119,10 @@ public class DoubleSettingGui extends AbstractSettingGui { protected void prepareReturnToDefault() { ItemStack item = new ItemStack(Material.COMMAND_BLOCK); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7eReset to default value"); - meta.setLore(Collections.singletonList("\u00A77Default value is " + displayValue(holder.defaultVal))); + meta.setLore(Collections.singletonList("\u00A77Default value is \u00A7e" + displayValue(holder.defaultVal))); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { event.setCancelled(true); @@ -160,7 +164,9 @@ public class DoubleSettingGui extends AbstractSettingGui { // "result" display ItemStack resultPaper = new ItemStack(Material.PAPER); ItemMeta resultMeta = resultPaper.getItemMeta(); - resultMeta.setDisplayName("\u00A7eValue: " + displayValue(now)); + assert resultMeta != null; + + resultMeta.setDisplayName("\u00A7fValue: \u00A7e" + displayValue(now)); resultPaper.setItemMeta(resultMeta); GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); @@ -178,11 +184,22 @@ public class DoubleSettingGui extends AbstractSettingGui { } private GuiItem getSetValueItem(Material mat, BigDecimal planned, String numberPrefix){ + // Create set item lore + ArrayList setLoreItem = new ArrayList<>(); + if(!holder.displayLore.isEmpty()){ + setLoreItem.addAll(holder.displayLore); + setLoreItem.add(""); + } + setLoreItem.add(AbstractSettingGui.CLICK_LORE); + + // Create & return set value item ItemStack item = new ItemStack(mat); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7e" + displayValue(now) + " -> " + displayValue(planned) + assert meta != null; + + meta.setDisplayName("\u00A7e" + displayValue(now) + " \u00A7f-> \u00A7e" + displayValue(planned) + " \u00A7r(" + numberPrefix + (displayValue(planned.subtract(now).abs()) + "\u00A7r)")); - meta.setLore(AbstractSettingGui.CLICK_LORE); + meta.setLore(setLoreItem); item.setItemMeta(meta); return new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); @@ -268,11 +285,12 @@ public class DoubleSettingGui extends AbstractSettingGui { stepLore = Collections.singletonList("\u00A77Click here to change the value by " + displayValue(stepValue)); clickEvent = updateStepValue(stepValue); } - stepName.append("Step of ").append(displayValue(stepValue)); + stepName.append("Step of \u00A7e").append(displayValue(stepValue)); // Create item stack then gui item ItemStack item = new ItemStack(stepMat); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName(stepName.toString()); meta.setLore(stepLore); @@ -338,6 +356,7 @@ public class DoubleSettingGui extends AbstractSettingGui { * @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 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 @@ -350,13 +369,16 @@ public class DoubleSettingGui extends AbstractSettingGui { * If step only contain 1 value, no step item should be displayed. * @return A factory for a double setting gui. */ - public static DoubleSettingFactory doubleFactory(@NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, + @NotNull + public static DoubleSettingFactory doubleFactory(@NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable List displayLore, int scale, boolean asPercentage, boolean nullOnZero, double min, double max, double defaultVal, double... steps) { return new DoubleSettingFactory( title, parent, configPath, config, + displayLore, scale, asPercentage, nullOnZero, min, max, defaultVal, steps); } @@ -367,6 +389,7 @@ public class DoubleSettingGui extends AbstractSettingGui { public static class DoubleSettingFactory extends SettingGuiFactory { @NotNull String title; + @NotNull ValueUpdatableGui parent; int scale; @@ -377,6 +400,9 @@ public class DoubleSettingGui extends AbstractSettingGui { BigDecimal defaultVal; BigDecimal[] steps; + @NotNull + List displayLore; + /** * Constructor for a double setting gui factory. * @@ -384,6 +410,7 @@ public class DoubleSettingGui extends AbstractSettingGui { * @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 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 @@ -396,8 +423,9 @@ public class DoubleSettingGui extends AbstractSettingGui { * If step only contain 1 value, no step item should be displayed. */ protected DoubleSettingFactory( - @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable List displayLore, int scale, boolean asPercentage, boolean nullOnZero, double min, double max, double defaultVal, double... steps) { super(configPath, config); @@ -414,6 +442,12 @@ public class DoubleSettingGui extends AbstractSettingGui { for (int i = 0; i < steps.length; i++) { this.steps[i] = BigDecimal.valueOf(steps[i]).setScale(scale, RoundingMode.HALF_UP); } + + if(displayLore == null){ + this.displayLore = Collections.emptyList(); + }else { + this.displayLore = displayLore; + } } /** @@ -449,7 +483,9 @@ public class DoubleSettingGui extends AbstractSettingGui { BigDecimal value = getConfiguredValue(); StringBuilder itemName = new StringBuilder("\u00A7a").append(name); - return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, displayValue(value, this.asPercentage)); + return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, + "\u00A7e" + displayValue(value, this.asPercentage), + this.displayLore, true); } public GuiItem getItem(Material itemMat){ diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java index c38b047..50df43b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/EnchantCostSettingsGui.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemFlag; 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.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; @@ -18,6 +19,8 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.util.MetricsUtil; import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.function.Consumer; /** @@ -78,6 +81,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui { // book display ItemStack bookItemstack = new ItemStack(Material.BOOK); ItemMeta bookMeta = bookItemstack.getItemMeta(); + assert bookMeta != null; bookMeta.setDisplayName("\u00A7aCost of an Enchantment by Book"); bookMeta.setLore(Arrays.asList( @@ -88,8 +92,9 @@ public class EnchantCostSettingsGui extends IntSettingsGui { // sword display ItemStack swordItemstack = new ItemStack(Material.WOODEN_SWORD); ItemMeta swordMeta = swordItemstack.getItemMeta(); - swordMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); + assert swordMeta != null; + swordMeta.addItemFlags(ItemFlag.values()); swordMeta.setDisplayName("\u00A7aCost of an Enchantment by Item"); swordMeta.setLore(Arrays.asList( "\u00A77Cost per result item level of an sacrifice enchantment", @@ -105,14 +110,15 @@ public class EnchantCostSettingsGui extends IntSettingsGui { protected void prepareReturnToDefault() { ItemStack item = new ItemStack(Material.COMMAND_BLOCK); ItemMeta meta = item.getItemMeta(); + assert meta != null; // assume holder is an instance of EnchantCostSettingFactory EnchantCostSettingFactory holder = (EnchantCostSettingFactory) this.holder; meta.setDisplayName("\u00A7eReset to default value"); meta.setLore(Arrays.asList( - "\u00A77Default item value is: " + holder.defaultVal, - "\u00A77Default book value is: " + holder.defaultBookVal)); + "\u00A77Default item value is: \u00A7e" + holder.defaultVal, + "\u00A77Default book value is: \u00A7e" + holder.defaultBookVal)); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { event.setCancelled(true); @@ -139,8 +145,10 @@ public class EnchantCostSettingsGui extends IntSettingsGui { int planned = Math.max(holder.min, nowBook - step); ItemStack item = new ItemStack(Material.RED_TERRACOTTA); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7e" + nowBook + " -> " + planned + " \u00A7r(\u00A7c-" + (nowBook - planned) + "\u00A7r)"); - meta.setLore(AbstractSettingGui.CLICK_LORE); + assert meta != null; + + meta.setDisplayName("\u00A7e" + nowBook + " \u00A7f-> \u00A7e" + planned + " \u00A7r(\u00A7c-" + (nowBook - planned) + "\u00A7r)"); + meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); item.setItemMeta(meta); minusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); @@ -155,8 +163,10 @@ public class EnchantCostSettingsGui extends IntSettingsGui { int planned = Math.min(holder.max, nowBook + step); ItemStack item = new ItemStack(Material.GREEN_TERRACOTTA); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7e" + nowBook + " -> " + planned + " \u00A7r(\u00A7a+" + (planned - nowBook) + "\u00A7r)"); - meta.setLore(AbstractSettingGui.CLICK_LORE); + assert meta != null; + + meta.setDisplayName("\u00A7e" + nowBook + " \u00A7f-> \u00A7e" + planned + " \u00A7r(\u00A7a+" + (planned - nowBook) + "\u00A7r)"); + meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); item.setItemMeta(meta); plusItem = new GuiItem(item, updateNowBookConsumer(planned), CustomAnvil.instance); @@ -165,12 +175,19 @@ public class EnchantCostSettingsGui extends IntSettingsGui { } pane.bindItem('P', plusItem); - // "result" display - ItemStack resultPaper = new ItemStack(Material.PAPER); - ItemMeta resultMeta = resultPaper.getItemMeta(); - resultMeta.setDisplayName("\u00A7eValue: " + nowBook); - resultPaper.setItemMeta(resultMeta); - GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); + // now value display + ItemStack nowPaper = new ItemStack(Material.PAPER); + ItemMeta nowMeta = nowPaper.getItemMeta(); + assert nowMeta != null; + + nowMeta.setDisplayName("\u00A7fValue: \u00A7e" + nowBook); + if(!holder.displayLore.isEmpty()){ + nowMeta.setLore(holder.displayLore); + } + + nowPaper.setItemMeta(nowMeta); + + GuiItem resultItem = new GuiItem(nowPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); pane.bindItem('V', resultItem); @@ -228,6 +245,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui { * @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 defaultItemVal Default item value if not found on the config. @@ -239,13 +257,15 @@ public class EnchantCostSettingsGui extends IntSettingsGui { * @return A factory for an enchant cost setting gui. */ public static EnchantCostSettingFactory enchantCostFactory( - @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable List displayLore, int min, int max, int defaultItemVal, int defaultBookVal, int... steps) { return new EnchantCostSettingFactory( title, parent, configPath, config, + displayLore, min, max, defaultItemVal, defaultBookVal, steps); } @@ -263,6 +283,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui { * @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 defaultItemVal Default item value if not found on the config. @@ -274,12 +295,14 @@ public class EnchantCostSettingsGui extends IntSettingsGui { */ protected EnchantCostSettingFactory( @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable List displayLore, int min, int max, int defaultItemVal, int defaultBookVal, int... steps) { super(title, parent, configPath, config, + displayLore, min, max, defaultItemVal, steps); this.defaultBookVal = defaultBookVal; } @@ -307,6 +330,9 @@ public class EnchantCostSettingsGui extends IntSettingsGui { return new EnchantCostSettingsGui(this, nowItem); } + public List getDisplayLore() { + return this.displayLore; + } } } \ No newline at end of file diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java index 7623ae5..9808a8b 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/GroupSelectSettingGui.java @@ -69,7 +69,7 @@ public class GroupSelectSettingGui extends AbstractSettingGui { Set illegalGroup = this.groupContainer.illegalGroups(); for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { if (illegalGroup.contains(group)) { - return; + continue; } filledEnchant.addItem(getGuiItemFromGroup(group)); } @@ -113,7 +113,7 @@ public class GroupSelectSettingGui extends AbstractSettingGui { meta.removeEnchant(Enchantment.DAMAGE_UNDEAD); meta.setLore(FALSE_LORE); } - meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_ENCHANTS); + meta.addItemFlags(ItemFlag.values()); item.setItemMeta(meta); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java index 10a97e1..13ba4f6 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/IntSettingsGui.java @@ -9,11 +9,13 @@ import org.bukkit.event.inventory.InventoryClickEvent; 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.config.ConfigHolder; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil; import java.util.Collections; @@ -67,9 +69,10 @@ public class IntSettingsGui extends AbstractSettingGui { protected void prepareReturnToDefault() { ItemStack item = new ItemStack(Material.COMMAND_BLOCK); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7eReset to default value"); - meta.setLore(Collections.singletonList("\u00A77Default value is: " + holder.defaultVal)); + meta.setLore(Collections.singletonList("\u00A77Default value is \u00A7e" + holder.defaultVal)); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { event.setCancelled(true); @@ -92,8 +95,10 @@ public class IntSettingsGui extends AbstractSettingGui { int planned = Math.max(holder.min, now - step); ItemStack item = new ItemStack(Material.RED_TERRACOTTA); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7e" + now + " -> " + planned + " \u00A7r(\u00A7c-" + (now - planned) + "\u00A7r)"); - meta.setLore(AbstractSettingGui.CLICK_LORE); + assert meta != null; + + meta.setDisplayName("\u00A7e" + now + " \u00A7f-> \u00A7e" + planned + " \u00A7r(\u00A7c-" + (now - planned) + "\u00A7r)"); + meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); item.setItemMeta(meta); minusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); @@ -109,8 +114,10 @@ public class IntSettingsGui extends AbstractSettingGui { int planned = Math.min(holder.max, now + step); ItemStack item = new ItemStack(Material.GREEN_TERRACOTTA); ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7e" + now + " -> " + planned + " \u00A7r(\u00A7a+" + (planned - now) + "\u00A7r)"); - meta.setLore(AbstractSettingGui.CLICK_LORE); + assert meta != null; + + meta.setDisplayName("\u00A7e" + now + " \u00A7f-> \u00A7e" + planned + " \u00A7r(\u00A7a+" + (planned - now) + "\u00A7r)"); + meta.setLore(Collections.singletonList(AbstractSettingGui.CLICK_LORE)); item.setItemMeta(meta); plusItem = new GuiItem(item, updateNowConsumer(planned), CustomAnvil.instance); @@ -122,8 +129,13 @@ public class IntSettingsGui extends AbstractSettingGui { // "result" display ItemStack resultPaper = new ItemStack(Material.PAPER); ItemMeta resultMeta = resultPaper.getItemMeta(); - resultMeta.setDisplayName("\u00A7eValue: " + now); + assert resultMeta != null; + + resultMeta.setDisplayName("\u00A7fValue: \u00A7e" + now); + resultMeta.setLore(holder.displayLore); + resultPaper.setItemMeta(resultMeta); + GuiItem resultItem = new GuiItem(resultPaper, GuiGlobalActions.stayInPlace, CustomAnvil.instance); pane.bindItem('v', resultItem); @@ -220,11 +232,12 @@ public class IntSettingsGui extends AbstractSettingGui { stepLore = Collections.singletonList("\u00A77Click here to change the value by " + stepValue); clickEvent = updateStepValue(stepValue); } - stepName.append("Step of: ").append(stepValue); + stepName.append("Step of: \u00A7e").append(stepValue); // Create item stack then gui item ItemStack item = new ItemStack(stepMat); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName(stepName.toString()); meta.setLore(stepLore); @@ -266,25 +279,28 @@ public class IntSettingsGui extends AbstractSettingGui { /** * 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 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. + * @param title The title of the gui. + * @param parent Parent gui to go back when completed. + * @param configPath Configuration path of this setting. + * @param config Configuration holder of this setting. + * @param displayLore Gui display item lore. + * @param min Minimum value of this setting. + * @param max Maximum value of this setting. + * @param defaultVal Default value if not found on the config. + * @param steps List of step the value can increment/decrement. + * List's size should be between 1 (included) and 5 (included). + * it is visually preferable to have an odd number of step. + * If step only contain 1 value, no step item should be displayed. * @return A factory for an int setting gui. */ public static IntSettingFactory intFactory(@NotNull String title, ValueUpdatableGui parent, String configPath, ConfigHolder config, + @Nullable List displayLore, int min, int max, int defaultVal, int... steps) { return new IntSettingFactory( title, parent, configPath, config, + displayLore, min, max, defaultVal, steps); } @@ -294,30 +310,36 @@ public class IntSettingsGui extends AbstractSettingGui { public static class IntSettingFactory extends SettingGuiFactory { @NotNull String title; + @NotNull ValueUpdatableGui parent; int min; int max; int defaultVal; int[] steps; + @NotNull + List displayLore; + /** * Constructor for an int setting 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. - * @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. + * @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. */ protected IntSettingFactory( - @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable List displayLore, int min, int max, int defaultVal, int... steps) { super(configPath, config); this.title = title; @@ -326,6 +348,12 @@ public class IntSettingsGui extends AbstractSettingGui { this.max = max; this.defaultVal = defaultVal; this.steps = steps; + + if(displayLore == null){ + this.displayLore = Collections.emptyList(); + }else { + this.displayLore = displayLore; + } } /** @@ -351,6 +379,44 @@ public class IntSettingsGui extends AbstractSettingGui { return new IntSettingsGui(this, now); } + /** + * Create a new int setting GuiItem. + * This item will create and open an int setting GUI from the factory. + * The item will have its value written in the lore part of the item. + * + * @param itemMat Displayed material of the item. + * @param name Name of the item. + * @return A formatted GuiItem that will create and open a GUI for the int setting. + */ + public GuiItem getItem( + @NotNull Material itemMat, + @NotNull String name + ) { + // Get item properties + int value = getConfiguredValue(); + StringBuilder itemName = new StringBuilder("\u00A7a").append(name); + + return GuiGlobalItems.createGuiItemFromProperties(this, itemMat, itemName, + "\u00A7e" + value, + this.displayLore, true); + } + + /** + * Create a new int setting GuiItem. + * This item will create and open an int setting GUI from the factory. + * The item will have its value written in the lore part of the item. + * Item's name will be the factory set title. + * + * @param itemMat Displayed material of the item. + * @return A formatted GuiItem that will create and open a GUI for the int setting. + */ + public GuiItem getItem( + @NotNull Material itemMat + ) { + String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); + return getItem(itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); + } + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java index d88452a..8d7cfdf 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/ItemSettingGui.java @@ -7,15 +7,19 @@ import io.delilaheve.CustomAnvil; import org.bukkit.Material; import org.bukkit.entity.HumanEntity; 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 org.jetbrains.annotations.Nullable; 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 xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.MetricsUtil; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -71,9 +75,10 @@ public class ItemSettingGui extends AbstractSettingGui { protected void prepareReturnToDefault() { ItemStack item = new ItemStack(Material.COMMAND_BLOCK); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7eReset to default value"); - meta.setLore(Collections.singletonList("\u00A77Default value is: " + holder.defaultVal)); + meta.setLore(Collections.singletonList("\u00A77Default value is \u00A7e" + holder.defaultVal)); item.setItemMeta(meta); returnToDefault = new GuiItem(item, event -> { event.setCancelled(true); @@ -98,6 +103,7 @@ public class ItemSettingGui extends AbstractSettingGui { }else{ displayedItem = new ItemStack(Material.BARRIER); ItemMeta valueMeta = displayedItem.getItemMeta(); + assert valueMeta != null; valueMeta.setDisplayName("\u00A74NO ITEM SET"); valueMeta.setLore(CLICK_LORE); @@ -122,7 +128,7 @@ public class ItemSettingGui extends AbstractSettingGui { /** * @return A consumer to update the current setting's value. */ - protected Consumer setItemAsCursor() { //TODO redo consumer + protected Consumer setItemAsCursor() { return event -> { event.setCancelled(true); @@ -161,20 +167,22 @@ public class ItemSettingGui extends AbstractSettingGui { /** * 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 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, ValueUpdatableGui parent, - String configPath, ConfigHolder config, - ItemStack defaultVal) { + 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); + defaultVal, displayLore); } /** @@ -183,27 +191,34 @@ public class ItemSettingGui extends AbstractSettingGui { public static class ItemSettingFactory extends SettingGuiFactory { @NotNull String title; + @NotNull ValueUpdatableGui parent; + @Nullable ItemStack defaultVal; + @NotNull + List displayLore; /** * Constructor for an item setting 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. - * @param defaultVal Default value if not found on the config. + * @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. */ protected ItemSettingFactory( - @NotNull String title, ValueUpdatableGui parent, - String configPath, ConfigHolder config, - ItemStack defaultVal) { + @NotNull String title, @NotNull ValueUpdatableGui parent, + @NotNull String configPath, @NotNull ConfigHolder config, + @Nullable ItemStack defaultVal, + String... displayLore) { super(configPath, config); this.title = title; this.parent = parent; this.defaultVal = defaultVal; + this.displayLore = Arrays.asList(displayLore); } /** @@ -221,6 +236,11 @@ public class ItemSettingGui extends AbstractSettingGui { return this.config.getConfig().getItemStack(this.configPath, this.defaultVal); } + @NotNull + public List getDisplayLore() { + return this.displayLore; + } + @Override public AbstractSettingGui create() { // Get current value or default @@ -229,5 +249,44 @@ public class ItemSettingGui extends AbstractSettingGui { return new ItemSettingGui(this, now); } + /** + * Create a new item setting GuiItem. + * This item will create and open an item setting GUI from the factory. + * Item's name will be the factory set title. + * + * @param name Name of the item. + * @return A formatted GuiItem that will create and open a GUI for the item setting. + */ + public GuiItem getItem(@NotNull String name) { + ItemStack item = getConfiguredValue(); + if(item == null || item.getType().isAir()){ + item = new ItemStack(Material.BARRIER); + }else{ + item = item.clone(); + } + ItemMeta meta = item.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7a" + name); + meta.setLore(getDisplayLore()); + meta.addItemFlags(ItemFlag.values()); + + item.setItemMeta(meta); + + return GuiGlobalItems.openSettingGuiItem(item, this); + } + + /** + * Create a new item setting GuiItem. + * This item will create and open an item setting GUI from the factory. + * Item's name will be the factory set title. + * + * @return A formatted GuiItem that will create and open a GUI for the item setting. + */ + public GuiItem getItem() { + String configPath = GuiGlobalItems.getConfigNameFromPath(getConfigPath()); + return getItem(CasedStringUtil.detectToUpperSpacedCase(configPath)); + } + } } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java new file mode 100644 index 0000000..9309bda --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/settings/MaterialSelectSettingGui.java @@ -0,0 +1,308 @@ +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.util.Pattern; +import io.delilaheve.CustomAnvil; +import org.bukkit.Material; +import org.bukkit.entity.HumanEntity; +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.gui.config.SelectMaterialContainer; +import xyz.alexcrea.cuanvil.gui.config.ask.ConfirmActionGui; +import xyz.alexcrea.cuanvil.gui.config.list.MappedElementListConfigGui; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; +import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; +import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; +import xyz.alexcrea.cuanvil.util.CasedStringUtil; + +import java.util.*; +import java.util.function.Consumer; + +public class MaterialSelectSettingGui extends MappedElementListConfigGui { + + private final SelectMaterialContainer selector; + private final Gui backGui; + private boolean instantRemove; + + private final List defaultMaterials; + private final EnumSet illegalMaterials; + private final int defaultMaterialHash; + private int nowMaterialHash; + + public MaterialSelectSettingGui( + @NotNull SelectMaterialContainer selector, + @NotNull String title, + @NotNull Gui backGui) { + super(title); + this.selector = selector; + this.backGui = backGui; + this.instantRemove = false; + + this.defaultMaterials = new ArrayList<>(this.selector.getSelectedMaterials()); + this.illegalMaterials = this.selector.illegalMaterials(); + + this.defaultMaterialHash = hashFromMaterialList(this.defaultMaterials); + this.nowMaterialHash = this.defaultMaterialHash; + + init(); + + // Change back item + this.backgroundPane.bindItem('B', GuiGlobalItems.backItem(backGui)); + } + + @Override + protected Pattern getBackgroundPattern(){ + return new Pattern( + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + GuiSharedConstant.EMPTY_GUI_FULL_LINE, + "BT1LAR1IS" + ); + } + + private GuiItem saveItem; + private GuiItem noChangeItem; + + private GuiItem instantRemoveOn; + private GuiItem instantRemoveOff; + + @Override + protected void prepareStaticValues() { + super.prepareStaticValues(); + + // Temporary leave item + GuiItem temporaryLeave = GuiGlobalItems.temporaryCloseGuiToSelectItem(Material.YELLOW_TERRACOTTA, this); + this.backgroundPane.bindItem('T', temporaryLeave); + + // Select new mat item + ItemStack selectItem = new ItemStack(Material.BLUE_STAINED_GLASS_PANE); + ItemMeta selectMeta = selectItem.getItemMeta(); + assert selectMeta != null; + + selectMeta.setDisplayName("\u00A7aAdd Item"); + selectMeta.setLore(Arrays.asList( + "\u00A77Click here with an item to add", + "\u00A77it's Material to the list.")); + + selectItem.setItemMeta(selectMeta); + + this.backgroundPane.bindItem('A', new GuiItem(selectItem, setItemAsCursor(), CustomAnvil.instance)); + + // Save item + this.saveItem = prepareSaveItem(); + + this.noChangeItem = GuiGlobalItems.noChangeItem(); + this.backgroundPane.bindItem('S', this.noChangeItem); + + // Instant Remove On item + ItemStack instantRemoveOnItem = new ItemStack(Material.LIME_STAINED_GLASS_PANE); + ItemMeta instantRemoveOnMeta = instantRemoveOnItem.getItemMeta(); + assert instantRemoveOnMeta != null; + + instantRemoveOnMeta.setDisplayName("\u00A7eInstant remove is \u00A7aEnabled \u00A7e!"); + instantRemoveOnMeta.setLore( + Collections.singletonList("\u00A77Click here to disable the instant remove")); + + instantRemoveOnItem.setItemMeta(instantRemoveOnMeta); + + // Instant Remove Off item + ItemStack instantRemoveOffItem = new ItemStack(Material.RED_STAINED_GLASS_PANE); + ItemMeta instantRemoveOffMeta = instantRemoveOffItem.getItemMeta(); + assert instantRemoveOffMeta != null; + + instantRemoveOffMeta.setDisplayName("\u00A7eInstant remove is \u00A7cDisabled \u00A7e!"); + instantRemoveOffMeta.setLore( + Collections.singletonList("\u00A77Click here to enable the instant remove")); + + instantRemoveOffItem.setItemMeta(instantRemoveOffMeta); + + // Instant Remove gui items + this.instantRemoveOn = new GuiItem(instantRemoveOnItem, (event -> { + this.instantRemove = false; + this.backgroundPane.bindItem('I', this.instantRemoveOff); + update(); + }), CustomAnvil.instance); + + this.instantRemoveOff = new GuiItem(instantRemoveOffItem, (event -> { + this.instantRemove = true; + this.backgroundPane.bindItem('I', this.instantRemoveOn); + update(); + }), CustomAnvil.instance); + + this.backgroundPane.bindItem('I', this.instantRemoveOff); + } + + private GuiItem prepareSaveItem() { + ItemStack saveItemStack = new ItemStack(GuiGlobalItems.DEFAULT_SAVE_ITEM); + ItemMeta saveMeta = saveItemStack.getItemMeta(); + assert saveMeta != null; + + saveMeta.setDisplayName("\u00A7aSave"); + + saveItemStack.setItemMeta(saveMeta); + + return new GuiItem(saveItemStack, event -> { + event.setCancelled(true); + + HumanEntity player = event.getWhoClicked(); + // Do not allow to save configuration if player do not have edit configuration permission + if (!player.hasPermission(CustomAnvil.editConfigPermission)) { + player.closeInventory(); + player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); + return; + } + if(testCantSave()) return; + + + // Save setting + EnumSet result = EnumSet.noneOf(Material.class); + result.addAll(this.elementGuiMap.keySet()); + + if(!this.selector.setSelectedMaterials(result)){ + player.sendMessage("\u00A7cSomething went wrong while saving the change of value."); + } + + // Return to parent + this.backGui.show(player); + + }, CustomAnvil.instance); + } + + /** + * @return A consumer to update the current setting's value. + */ + protected Consumer setItemAsCursor() { + return event -> { + event.setCancelled(true); + + HumanEntity player = event.getWhoClicked(); + ItemStack cursor = player.getItemOnCursor(); + + // Test if cursor material allowed + Material cursorMat = cursor.getType(); + if(cursorMat.isAir()) return; + if(this.illegalMaterials.contains(cursorMat)) return; + + // Update gui only if item did not exist before. + if(!this.elementGuiMap.containsKey(cursorMat)){ + updateValueForGeneric(cursorMat, true); + this.nowMaterialHash ^= cursorMat.hashCode(); + + setSaveItem(); + update(); + } + }; + } + + @Override + protected ItemStack createItemForGeneric(Material material) { + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + + if(meta == null) return item; + meta.setDisplayName("\u00A7a" + CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase())); + meta.setLore(Collections.singletonList("\u00A77Click here to remove this material from the list")); + meta.addItemFlags(ItemFlag.values()); + + item.setItemMeta(meta); + + return item; + } + + @Override + protected List getEveryDisplayableInstanceOfGeneric() { + return this.defaultMaterials; + } + + @Override + protected void updateElement(Material material, GuiItem element) { + // Nothing happen here I think + } + + @Override + protected GuiItem newElementRequested(Material material, GuiItem newItem) { + newItem.setAction(event -> { + if(this.instantRemove){ + removeMaterial(material); + }else { + String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase()); + + // Create and show confirm remove gui. + ConfirmActionGui confirmGui = new ConfirmActionGui( + "Remove " + materialName, + "\u00A77Confirm Remove " + materialName.toLowerCase() + " from this list.", + this, this, + () -> { + removeMaterial(material); + return true; + }, false + ); + confirmGui.show(event.getWhoClicked()); + + } + }); + return newItem; + } + + private void removeMaterial(Material material) { + if(this.elementGuiMap.containsKey(material)){ + this.nowMaterialHash ^= material.hashCode(); + setSaveItem(); + removeGeneric(material); + } + + } + + @Override + protected GuiItem findItemFromElement(Material generic, GuiItem element) { + return element; + } + + @Override + protected GuiItem findGuiItemForRemoval(Material generic, GuiItem element) { + return element; + } + + private static int hashFromMaterialList(List materialList){ + int defaultMaterialHash = 0; + for (Material material : materialList) { + defaultMaterialHash ^= material.hashCode(); + } + return defaultMaterialHash; + } + + private void setSaveItem() { + if(testCantSave()){ + this.backgroundPane.bindItem('S', this.noChangeItem); + }else{ + this.backgroundPane.bindItem('S', this.saveItem); + } + + } + + private boolean testCantSave() { + return this.defaultMaterialHash == this.nowMaterialHash; + } + + + // Unused functions. + @Override + protected GuiItem prepareCreateNewItem() {// Not used + return null; + } + @Override + protected Consumer prepareCreateItemConsumer(HumanEntity player) {// Not used + return null; + } + + @Override + protected String genericDisplayedName() {// Not Used + return null; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalActions.java b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalActions.java index e8c8334..6be8d83 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalActions.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalActions.java @@ -97,6 +97,7 @@ public class GuiGlobalActions { */ public static @NotNull Consumer openGuiAction(@NotNull Gui goal) { return event -> { + event.setCancelled(true); HumanEntity player = event.getWhoClicked(); // Do not allow to open inventory if player do not have edit configuration permission if (!player.hasPermission(CustomAnvil.editConfigPermission)) { @@ -104,7 +105,6 @@ public class GuiGlobalActions { player.sendMessage(NO_EDIT_PERM); return; } - event.setCancelled(true); goal.show(player); }; } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java index d72a988..828eb90 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiGlobalItems.java @@ -12,12 +12,10 @@ import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; -import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui; -import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui; -import xyz.alexcrea.cuanvil.gui.config.settings.ItemSettingGui; -import xyz.alexcrea.cuanvil.util.CasedStringUtil; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; /** * A utility class to store function that create generic GUI item. @@ -30,6 +28,8 @@ public class GuiGlobalItems { static { BACK_ITEM = new ItemStack(Material.BARRIER); ItemMeta meta = BACK_ITEM.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A7cBack"); BACK_ITEM.setItemMeta(meta); } @@ -80,6 +80,8 @@ public class GuiGlobalItems { public static GuiItem backgroundItem(Material backgroundMat) { ItemStack item = new ItemStack(backgroundMat); ItemMeta meta = item.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A7c"); item.setItemMeta(meta); return new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); @@ -117,8 +119,8 @@ public class GuiGlobalItems { addBackgroundItem(target, DEFAULT_BACKGROUND_MAT); } - private static final Material DEFAULT_SAVE_ITEM = Material.LIME_DYE; - private static final Material DEFAULT_NO_CHANGE_ITEM = Material.GRAY_DYE; + public static final Material DEFAULT_SAVE_ITEM = Material.LIME_DYE; + public static final Material DEFAULT_NO_CHANGE_ITEM = Material.GRAY_DYE; /** * Create a new save setting GuiItem. @@ -135,6 +137,8 @@ public class GuiGlobalItems { ItemStack item = new ItemStack(DEFAULT_SAVE_ITEM); ItemMeta meta = item.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A7aSave"); item.setItemMeta(meta); return new GuiItem(item, @@ -148,6 +152,8 @@ public class GuiGlobalItems { static { ItemStack item = new ItemStack(DEFAULT_NO_CHANGE_ITEM); ItemMeta meta = item.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A77No change. can't save."); item.setItemMeta(meta); NO_CHANGE_ITEM = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); @@ -181,156 +187,40 @@ public class GuiGlobalItems { // Prefix of the one line lore that will be added to setting's item. public static final String SETTING_ITEM_LORE_PREFIX = "\u00A77value: "; - /** - * Create a new Boolean setting GuiItem. - * This item will create and open a boolean setting GUI from the factory. - * The item will have its value written in the lore part of the item. - * - * @param factory The setting's GUI factory. - * @param name Name of the item. - * @return A formatted GuiItem that will create and open a GUI for the boolean setting. - */ - public static GuiItem boolSettingGuiItem( - @NotNull BoolSettingsGui.BoolSettingFactory factory, - @NotNull String name - ) { - // Get item properties - boolean value = factory.getConfiguredValue(); - - Material itemMat; - StringBuilder itemName = new StringBuilder("\u00A7"); - if (value) { - itemMat = Material.GREEN_TERRACOTTA; - itemName.append("a"); - } else { - itemMat = Material.RED_TERRACOTTA; - itemName.append("c"); - } - itemName.append(name); - - return createGuiItemFromProperties(factory, itemMat, itemName, value); - } - - /** - * Create a new boolean setting GuiItem. - * This item will create and open a boolean setting GUI from the factory. - * The item will have its value written in the lore part of the item. - * Item's name will be the factory set title. - * - * @param factory The setting's GUI factory. - * @return A formatted GuiItem that will create and open a GUI for the boolean setting. - */ - public static GuiItem boolSettingGuiItem( - @NotNull BoolSettingsGui.BoolSettingFactory factory - ) { - String configPath = getConfigNameFromPath(factory.getConfigPath()); - return boolSettingGuiItem(factory, CasedStringUtil.snakeToUpperSpacedCase(configPath)); - } - - /** - * Create a new int setting GuiItem. - * This item will create and open an int setting GUI from the factory. - * The item will have its value written in the lore part of the item. - * - * @param factory The setting's GUI factory. - * @param itemMat Displayed material of the item. - * @param name Name of the item. - * @return A formatted GuiItem that will create and open a GUI for the int setting. - */ - public static GuiItem intSettingGuiItem( - @NotNull IntSettingsGui.IntSettingFactory factory, - @NotNull Material itemMat, - @NotNull String name - ) { - // Get item properties - int value = factory.getConfiguredValue(); - StringBuilder itemName = new StringBuilder("\u00A7a").append(name); - - return createGuiItemFromProperties(factory, itemMat, itemName, value); - } - - /** - * Create a new int setting GuiItem. - * This item will create and open an int setting GUI from the factory. - * The item will have its value written in the lore part of the item. - * Item's name will be the factory set title. - * - * @param factory The setting's GUI factory. - * @param itemMat Displayed material of the item. - * @return A formatted GuiItem that will create and open a GUI for the int setting. - */ - public static GuiItem intSettingGuiItem( - @NotNull IntSettingsGui.IntSettingFactory factory, - @NotNull Material itemMat - ) { - String configPath = getConfigNameFromPath(factory.getConfigPath()); - return intSettingGuiItem(factory, itemMat, CasedStringUtil.detectToUpperSpacedCase(configPath)); - } - - /** - * Create a new item setting GuiItem. - * This item will create and open an item setting GUI from the factory. - * Item's name will be the factory set title. - * - * @param factory The setting's GUI factory. - * @param name Name of the item. - * @return A formatted GuiItem that will create and open a GUI for the item setting. - */ - public static GuiItem itemSettingGuiItem( - @NotNull ItemSettingGui.ItemSettingFactory factory, - @NotNull String name - ) { - ItemStack item = factory.getConfiguredValue(); - if(item == null || item.getType().isAir()){ - item = new ItemStack(Material.BARRIER); - }else{ - item = item.clone(); - } - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("\u00A7a" + name); - - item.setItemMeta(meta); - - return openSettingGuiItem(item, factory); - } - - /** - * Create a new item setting GuiItem. - * This item will create and open an item setting GUI from the factory. - * Item's name will be the factory set title. - * - * @param factory The setting's GUI factory. - * @return A formatted GuiItem that will create and open a GUI for the item setting. - */ - public static GuiItem itemSettingGuiItem( - @NotNull ItemSettingGui.ItemSettingFactory factory - ) { - String configPath = getConfigNameFromPath(factory.getConfigPath()); - return itemSettingGuiItem(factory, CasedStringUtil.detectToUpperSpacedCase(configPath)); - } - /** * Create an arbitrary GuiItem from a unique setting and item's property. * - * @param factory The setting's GUI factory. - * @param itemMat Displayed material of the item. - * @param itemName Name of the item. - * @param value Value of the setting when the item is created. - * Will not update automatically, if the setting's value change, the item need to be created again. + * @param factory The setting's GUI factory. + * @param itemMat Displayed material of the item. + * @param itemName Name of the item. + * @param value Value of the setting when the item is created. + * Will not update automatically, if the setting's value change, the item need to be created again. + * @param displayLore Gui display item lore. * @return A formatted GuiItem that will create and open a GUI for the setting. */ public static GuiItem createGuiItemFromProperties( @NotNull AbstractSettingGui.SettingGuiFactory factory, @NotNull Material itemMat, @NotNull StringBuilder itemName, - @NotNull Object value + @NotNull Object value, + @NotNull List displayLore, + boolean displayValuePrefix ) { + // Prepare lore + ArrayList lore = new ArrayList<>(); + lore.add((displayValuePrefix ? SETTING_ITEM_LORE_PREFIX : "") + value); + if(!displayLore.isEmpty()){ + lore.add(""); + lore.addAll(displayLore); + } + // Create & initialise item ItemStack item = new ItemStack(itemMat); ItemMeta itemMeta = item.getItemMeta(); + assert itemMeta != null; itemMeta.setDisplayName(itemName.toString()); - itemMeta.setLore(Collections.singletonList(SETTING_ITEM_LORE_PREFIX + value)); + itemMeta.setLore(lore); itemMeta.addItemFlags(ItemFlag.values()); item.setItemMeta(itemMeta); @@ -355,6 +245,7 @@ public class GuiGlobalItems { public static GuiItem temporaryCloseGuiToSelectItem(Material itemMaterial, Gui openBack){ ItemStack item = new ItemStack(itemMaterial); ItemMeta meta = item.getItemMeta(); + assert meta != null; meta.setDisplayName("\u00A7eTemporary close this menu"); meta.setLore(Collections.singletonList("\u00A77Allow you to chose other item then return here.")); diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiSharedConstant.java b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiSharedConstant.java index 0ad90a6..1c492b1 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiSharedConstant.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/util/GuiSharedConstant.java @@ -55,20 +55,33 @@ public class GuiSharedConstant { public static final ItemStack CANCEL_ITEM; public static final ItemStack CONFIRM_ITEM; + public static final ItemStack CONFIRM_PERMANENT_ITEM; static { CANCEL_ITEM = new ItemStack(Material.RED_TERRACOTTA); ItemMeta meta = CANCEL_ITEM.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A7cCancel"); meta.setLore(Collections.singletonList("\u00A77Cancel current action and return to previous menu.")); CANCEL_ITEM.setItemMeta(meta); CONFIRM_ITEM = new ItemStack(Material.GREEN_TERRACOTTA); meta = CONFIRM_ITEM.getItemMeta(); + assert meta != null; + + meta.setDisplayName("\u00A7aConfirm"); + meta.setLore(Collections.singletonList("\u00A77Confirm current action.")); + CONFIRM_ITEM.setItemMeta(meta); + + CONFIRM_PERMANENT_ITEM = new ItemStack(Material.GREEN_TERRACOTTA); + meta = CONFIRM_PERMANENT_ITEM.getItemMeta(); + assert meta != null; + meta.setDisplayName("\u00A7aConfirm"); meta.setLore(Arrays.asList("\u00A77Confirm current action.", "\u00A74Cation: This action can't be canceled.")); - CONFIRM_ITEM.setItemMeta(meta); + CONFIRM_PERMANENT_ITEM.setItemMeta(meta); } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt index c9db197..841773f 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/command/ReloadExecutor.kt @@ -5,11 +5,7 @@ import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import xyz.alexcrea.cuanvil.config.ConfigHolder -import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui -import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui -import xyz.alexcrea.cuanvil.gui.config.global.EnchantCostConfigGui -import xyz.alexcrea.cuanvil.gui.config.global.EnchantLimitConfigGui -import xyz.alexcrea.cuanvil.gui.config.global.UnitRepairConfigGui +import xyz.alexcrea.cuanvil.gui.config.global.* import xyz.alexcrea.cuanvil.util.MetricsUtil class ReloadExecutor : CommandExecutor { @@ -43,8 +39,11 @@ class ReloadExecutor : CommandExecutor { BasicConfigGui.INSTANCE.updateGuiValues() EnchantCostConfigGui.INSTANCE.updateGuiValues() EnchantLimitConfigGui.INSTANCE.updateGuiValues() + EnchantConflictGui.INSTANCE.reloadValues() + GroupConfigGui.INSTANCE.reloadValues() UnitRepairConfigGui.INSTANCE.reloadValues() + CustomRecipeConfigGui.INSTANCE.reloadValues() // & update metric MetricsUtil.testIfConfigIsDefault() diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt index f13b039..289f058 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/AbstractMaterialGroup.kt @@ -60,6 +60,10 @@ abstract class AbstractMaterialGroup(private val name: String) { return name } + override fun toString(): String { + return name + } + /** * Update the contained groups of this group */ @@ -88,4 +92,6 @@ abstract class AbstractMaterialGroup(private val name: String) { return Material.PAPER } + abstract fun updateMaterials() + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt index f4c9b47..e295396 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/EnchantConflictManager.kt @@ -82,7 +82,7 @@ class EnchantConflictManager { // Read and add enchantment to conflict val enchantList = section.getStringList(ENCH_LIST_PATH) for (enchantName in enchantList) { - val enchant = getEnchantByName(enchantName); + val enchant = getEnchantByName(enchantName) if (enchant == null) { if (!futureUse) { CustomAnvil.instance.logger.warning("Enchantment $enchantName do not exist but was asked for conflict $conflictName") @@ -110,7 +110,7 @@ class EnchantConflictManager { } val enchantKey = NamespacedKey.minecraft(enchantName) - return Enchantment.getByKey(enchantKey); + return Enchantment.getByKey(enchantKey) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt index 609f0f5..247cb83 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ExcludeGroup.kt @@ -47,6 +47,15 @@ class ExcludeGroup(name: String) : AbstractMaterialGroup(name) { return includedGroup } + override fun updateMaterials() { + groupItems.clear() + groupItems.addAll(includedMaterial) + + includedGroup.forEach { group -> + groupItems.addAll(group.getMaterials()) + } + } + override fun getMaterials(): EnumSet { return groupItems } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt index 33354f1..968ceb1 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/IncludeGroup.kt @@ -45,7 +45,15 @@ class IncludeGroup(name: String) : AbstractMaterialGroup(name) { override fun setNonGroupInheritedMaterials(materials: EnumSet) { super.setNonGroupInheritedMaterials(materials) - // Update group items + + updateMaterials() + } + + override fun getGroups(): MutableSet { + return includedGroup + } + + override fun updateMaterials() { groupItems.clear() groupItems.addAll(includedMaterial) @@ -54,10 +62,6 @@ class IncludeGroup(name: String) : AbstractMaterialGroup(name) { } } - override fun getGroups(): MutableSet { - return includedGroup - } - override fun getMaterials(): EnumSet { return groupItems } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ItemGroupManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ItemGroupManager.kt index e1fb59b..65eef34 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/group/ItemGroupManager.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/group/ItemGroupManager.kt @@ -9,13 +9,13 @@ class ItemGroupManager { companion object { // Path for group type - private const val GROUP_TYPE_PATH = "type" + const val GROUP_TYPE_PATH = "type" // Path for included items list - private const val MATERIAL_LIST_PATH = "items" + const val MATERIAL_LIST_PATH = "items" // Path for included groups list - private const val GROUP_LIST_PATH = "groups" + const val GROUP_LIST_PATH = "groups" // Temporary list of elements in default config that are use in future private val FUTURE_MATERIAL = setOf("PIGLIN_HEAD", "BRUSH") @@ -35,6 +35,15 @@ class ItemGroupManager { } } + // Create group with existing groups + fun createGroup( + config: ConfigurationSection, + name: String + ): AbstractMaterialGroup{ + return createGroup(config, groupMap.keys, name) + } + + // Create group by key private fun createGroup( config: ConfigurationSection, @@ -46,7 +55,7 @@ class ItemGroupManager { // Create Material group according to the group type val group: AbstractMaterialGroup - if (GroupType.EXCLUDE.equal(groupType)) { + if (groupType != null && GroupType.EXCLUDE.equal(groupType)) { group = ExcludeGroup(key) } else { group = IncludeGroup(key) @@ -124,7 +133,7 @@ class ItemGroupManager { } -enum class GroupType(private val groupID: String) { +enum class GroupType(val groupID: String) { INCLUDE("include"), EXCLUDE("exclude") diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt index 9be7c67..c7e3038 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt @@ -32,20 +32,20 @@ class AnvilCustomRecipe( const val RESULT_ITEM_CONFIG = "result_item" - val DEFAULT_EXACT_COUNT_CONFIG = true + const val DEFAULT_EXACT_COUNT_CONFIG = true //val DEFAULT_EXACT_LEFT_CONFIG = true //val DEFAULT_EXACT_RIGHT_CONFIG = true - val DEFAULT_XP_COST_CONFIG = 1 + const val DEFAULT_XP_COST_CONFIG = 1 val DEFAULT_LEFT_ITEM_CONFIG: ItemStack? = null val DEFAULT_RIGHT_ITEM_CONFIG: ItemStack? = null - val DEFAULT_RESULT_ITEM_CONFIG: ItemStack? = null; + val DEFAULT_RESULT_ITEM_CONFIG: ItemStack? = null val XP_COST_CONFIG_RANGE = 0..255 fun getFromConfig(name: String, configSection: ConfigurationSection?): AnvilCustomRecipe? { - if(configSection == null) return null; + if(configSection == null) return null return AnvilCustomRecipe( name, configSection.getBoolean(EXACT_COUNT_CONFIG, DEFAULT_EXACT_COUNT_CONFIG), @@ -89,7 +89,7 @@ class AnvilCustomRecipe( if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) { - ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE); + ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE) } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7e2435c..98784be 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,11 +1,11 @@ -# Whether all anvil actions should be capped +# Whether all anvil actions cost should be capped # # If true, all anvil repairs will max out at the value of limit_repair_value limit_repair_cost: false # Value to limit repair costs to when limit_repair_cost is true # -# Valid range of 1 - 39 (vanilla will consider 40+ as "too expensive") +# Valid values include 1 to 39 (vanilla will consider 40+ as "too expensive") limit_repair_value: 39 # Whether the anvil's repair limit should be removed entirely @@ -13,31 +13,32 @@ limit_repair_value: 39 # The anvil will still visually display "too expensive" however the action will be completable remove_repair_limit: false -# Value added to the anvil when the item is repaired by another item of the same type +# XP Level amount added to the anvil when the item is repaired by another item of the same type # -# Valid range of 0 - 255 +# Valid values include 0 to 255 item_repair_cost: 2 -# Value added to the anvil when the item is repaired by an "unit" -# For example, a diamond on a diamond sword +# XP Level amount added to the anvil when the item is repaired by an "unit" +# For example: a Diamond on a Diamond Sword +# What's considered unit for what can be edited on the unit repair configuration. # -# Valid range of 0 - 255 +# Valid values include 0 to 255 unit_repair_cost: 1 -# Value added to the anvil when the item is renamed +# XP Level amount added to the anvil when the item is renamed # -# Valid range of 0 - 255 +# Valid values include 0 to 255 item_rename_cost: 1 -# Value added to the anvil when a sacrifice enchantment conflict -# with one of the left item enchantment +# XP Level amount added to the anvil when a sacrifice enchantment +# conflict with one of the left item enchantment # -# Valid range of 0 - 255 +# Valid values include 0 to 255 sacrifice_illegal_enchant_cost: 1 # Default limit to apply to any enchants missing from override_limits # -# Valid range of 1 - 255 +# Valid values include 1 to 255 default_limit: 5 # Override limits for specific enchants diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f7e12fa..53c5951 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ main: io.delilaheve.CustomAnvil name: CustomAnvil prefix: "Custom Anvil" -version: 1.4.3a +version: 1.4.4 description: Allow to customise anvil mechanics api-version: 1.18 load: POSTWORLD