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..1b640b3 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 groups 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/global/GroupConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java index 5d5f89b..f0a2e3d 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/GroupConfigGui.java @@ -18,7 +18,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class GroupConfigGui extends MappedGuiListConfigGui { +public class GroupConfigGui extends MappedGuiListConfigGui { public final static GroupConfigGui INSTANCE = new GroupConfigGui(); @@ -31,15 +31,15 @@ public class GroupConfigGui extends MappedGuiListConfigGui getEveryDisplayableInstanceOfGeneric() { - ArrayList includeGroups = new ArrayList<>(); + protected List getEveryDisplayableInstanceOfGeneric() { + ArrayList includeGroups = new ArrayList<>(); for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { if(group instanceof IncludeGroup){ - includeGroups.add(group); + includeGroups.add((IncludeGroup) group); } } return includeGroups; } @Override - protected GroupConfigSubSettingGui newInstanceOfGui(AbstractMaterialGroup group, GuiItem item) { + protected GroupConfigSubSettingGui newInstanceOfGui(IncludeGroup group, GuiItem item) { return new GroupConfigSubSettingGui(this, group, item); } @@ -70,14 +70,14 @@ public class GroupConfigGui extends MappedGuiListConfigGui { event.setCancelled(true); EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui( @@ -184,27 +180,7 @@ 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(); @@ -288,7 +264,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 index 4ccf7d8..744c2d4 100644 --- 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 @@ -4,36 +4,37 @@ 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.Bukkit; 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.AbstractMaterialGroup; -import xyz.alexcrea.cuanvil.group.ItemGroupManager; +import xyz.alexcrea.cuanvil.group.*; +import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer; 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.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.Collections; +import java.util.*; import java.util.function.Consumer; import java.util.function.Supplier; -public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { +public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implements SelectGroupContainer { private final GroupConfigGui parent; - private final AbstractMaterialGroup group; + private final IncludeGroup group; private final PatternPane pane; public GroupConfigSubSettingGui( @NotNull GroupConfigGui parent, - @NotNull AbstractMaterialGroup group, + @NotNull IncludeGroup group, @NotNull GuiItem item) { super(item, 3, group.getName()); this.parent = parent; @@ -50,6 +51,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { prepareStaticValues(); } + private GuiItem materialSelection; + private GuiItem groupSelection; private void prepareStaticValues() { GuiGlobalItems.addBackItem(this.pane, this.parent); GuiGlobalItems.addBackgroundItem(this.pane); @@ -58,15 +61,31 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA); ItemMeta deleteMeta = deleteItem.getItemMeta(); - deleteMeta.setDisplayName("\u00A74DELETE RECIPE"); + deleteMeta.setDisplayName("\u00A74DELETE GROUP"); deleteMeta.setLore(Collections.singletonList("\u00A7cCaution with this button !")); deleteItem.setItemMeta(deleteMeta); - this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); + 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); + + }, CustomAnvil.instance); + + this.groupSelection = new GuiItem(new ItemStack(Material.CHEST), (event) -> { + event.setCancelled(true); + GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( + "\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.group.toString()) + " \u00A7rGroups", + this, this, 0); + enchantGui.show(event.getWhoClicked()); + }, CustomAnvil.instance); + + this.pane.bindItem('1', this.materialSelection); + this.pane.bindItem('2', this.groupSelection); } - private @NotNull Consumer openGuiAction() { + private @NotNull Consumer openGuiAndCheckAction() { ConfirmActionGui deleteGui = createDeleteGui(); return event -> { event.setCancelled(true); @@ -77,7 +96,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { player.sendMessage(GuiGlobalActions.NO_EDIT_PERM); return; } - // TODO test if group is used & cancel if so + // test if group is used & cancel & warn user if so + if(testAndWarnIfUsed(player)) return; deleteGui.show(player); }; @@ -85,12 +105,22 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { 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(); - // TODO test if group is used & cancel if so - // TODO remove group - Bukkit.broadcastMessage("todo"); + // 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; @@ -107,21 +137,157 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui { ); } + 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() { - // TODO update value from config to conflict - // Parent should call updateLocal with this call this.parent.updateValueForGeneric(this.group, true); + } @Override public void updateLocal() { + // Prepare group lore + List groupLore = SelectGroupContainer.getGroupLore(this, "group", "include"); + // Configure enchant setting item + ItemStack matSelectItem = this.materialSelection.getItem(); + ItemMeta matSelectMeta = matSelectItem.getItemMeta(); + + matSelectMeta.setDisplayName("\u00A7aSelect included \u00A7eMaterials \u00A7aSettings"); + matSelectMeta.setLore(Collections.emptyList()); // temporary + 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() { } + + // ---------------------------- + // SelectGroupContainer 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(this.group.getName()+"."+ItemGroupManager.GROUP_LIST_PATH, groupNames); + + // Try to update referencing group. kind of expensive operation in some case. + for (AbstractMaterialGroup otherGroup : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { + if(otherGroup.getGroups().contains(group)){ + Set groupClone = new HashSet<>(otherGroup.getGroups()); + updateGroup(otherGroup, groupClone); + } + } + + // Update parent & local by extension + if(group instanceof IncludeGroup){ + this.parent.updateValueForGeneric((IncludeGroup) group, true); + } + + // We assume a backup & save call we 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; + } } 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); }