Last part of the config gui. (#7)

Also:
- Fix Custom recipe config GUI not being reloaded on reload config command
- Added description text to some values.
This commit is contained in:
alexcrea 2024-05-06 20:51:13 +00:00 committed by GitHub
commit 8cf84caf3c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 1528 additions and 410 deletions

View file

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

View file

@ -4,7 +4,7 @@ plugins {
}
group = "xyz.alexcrea"
version = "1.4.3a"
version = "1.4.4"
repositories {
mavenCentral()

View file

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

View file

@ -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<AbstractMaterialGroup> illegalGroups();
static List<String> getGroupLore(SelectGroupContainer container, String containerType, String groupAction){
// Prepare group lore
ArrayList<String> groupLore = new ArrayList<>();
groupLore.add("\u00A77Allow you to select a list of \u00A73Groups \u00A77that this " + containerType + " should " + groupAction);
Set<AbstractMaterialGroup> 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<AbstractMaterialGroup> 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;
}
}

View file

@ -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<Material> illegalMaterials();
static List<String> getMaterialLore(SelectMaterialContainer container, String containerType, String action){
// Prepare material lore
ArrayList<String> groupLore = new ArrayList<>();
groupLore.add("\u00A77Allow you to select a list of \u00A7ematerials \u00A77that this " + containerType + " should " + action);
Set<Material> 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<Material> 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;
}
}

View file

@ -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<Boolean> onConfirm) {
Gui backOnCancel, Gui backOnConfirm, Supplier<Boolean> 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<Boolean> onConfirm){
this(title, actionDescription, backOnCancel, backOnConfirm, onConfirm, true);
}
@Override
protected Pattern getGuiPattern() {

View file

@ -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 {

View file

@ -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();

View file

@ -41,6 +41,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
// edit displayed item
ItemMeta meta = displaydItem.getItemMeta();
assert meta != null;
meta.setDisplayName("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(recipe.toString()) + " \u00A7fCustom recipe");
meta.addItemFlags(ItemFlag.values());
@ -73,8 +74,8 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
// Create new empty conflict and display it to the admin
AnvilCustomRecipe recipe = new AnvilCustomRecipe(
name,
AnvilCustomRecipe.Companion.getDEFAULT_EXACT_COUNT_CONFIG(),
AnvilCustomRecipe.Companion.getDEFAULT_XP_COST_CONFIG(),
AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG,
AnvilCustomRecipe.DEFAULT_XP_COST_CONFIG,
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(),
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(),
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG());

View file

@ -2,6 +2,7 @@ package xyz.alexcrea.cuanvil.gui.config.global;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
@ -57,11 +58,13 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
ItemStack item = new ItemStack(conflict.getRepresentativeMaterial());
ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.addItemFlags(ItemFlag.values());
meta.setDisplayName("\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(conflict.toString()) + " \u00A7fConflict");
meta.setLore(Arrays.asList(
"\u00A77Enchantment count: \u00A7e" + conflict.getEnchants().size(),
"\u00A77Group count: \u00A7e" + conflict.getCantConflictGroup().getGroups().size(),
"\u00A77Enchantment count: \u00A7e" + conflict.getEnchants().size(),
"\u00A77Group count: \u00A7e" + conflict.getCantConflictGroup().getGroups().size(),
"\u00A77Min enchantments count: \u00A7e" + conflict.getMinBeforeBlock()
));

View file

@ -12,7 +12,9 @@ import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/**
@ -32,7 +34,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
* Constructor of this Global gui for enchantment cost settings.
*/
private EnchantCostConfigGui() {
super("\u00A78Enchantment Level Limit");
super("\u00A78Enchantment Level Cost");
}
@ -49,7 +51,12 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
}
return EnchantCostSettingsGui.enchantCostFactory(prettyKey + " Level Cost", this,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, 0, 255,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList(
"\u00A77How many level should " + prettyKey,
"\u00A77cost when applied by book or by another item."
),
0, 255,
rarity.getItemValue(), rarity.getBookValue(),
1, 10, 50);
}
@ -63,12 +70,22 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
// Create item
ItemStack item = new ItemStack(Material.ENCHANTED_BOOK);
ItemMeta itemMeta = item.getItemMeta();
assert itemMeta != null;
// Prepare lore
List<String> lore = new ArrayList<>();
lore.add("\u00A77Item Cost: \u00A7e" + itemCost);
lore.add("\u00A77Book Cost: \u00A7e" + bookCost);
List<String> 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);

View file

@ -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<IntSettingsG
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key);
return IntSettingsGui.intFactory(prettyKey + " Level Limit", this,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, 0, 255,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
Collections.singletonList(
"\u00A77Maximum applied level of " + prettyKey
),
0, 255,
enchant.getMaxLevel(),
1, 5, 10, 50, 100);
}
@Override
public GuiItem getItemFromFactory(IntSettingsGui.IntSettingFactory inventoryFactory) {
return GuiGlobalItems.intSettingGuiItem(inventoryFactory,
return inventoryFactory.getItem(
Material.ENCHANTED_BOOK,
inventoryFactory.getTitle());
}

View file

@ -0,0 +1,84 @@
package xyz.alexcrea.cuanvil.gui.config.global;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.group.AbstractMaterialGroup;
import xyz.alexcrea.cuanvil.group.GroupType;
import xyz.alexcrea.cuanvil.group.IncludeGroup;
import xyz.alexcrea.cuanvil.group.ItemGroupManager;
import xyz.alexcrea.cuanvil.gui.config.list.MappedGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.list.elements.GroupConfigSubSettingGui;
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupConfigSubSettingGui> {
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<IncludeGroup> getEveryDisplayableInstanceOfGeneric() {
ArrayList<IncludeGroup> 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);
}
}

View file

@ -48,6 +48,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
ItemStack item = new ItemStack(material);
ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.setDisplayName("\u00A7eRepaired by " +materialName);
meta.setLore(Arrays.asList(
@ -78,6 +79,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
// Create new conflict item
ItemStack createItem = new ItemStack(Material.PAPER);
ItemMeta createMeta = createItem.getItemMeta();
assert createMeta != null;
createMeta.setDisplayName("\u00A7aSelect a new unit material");
createMeta.setLore(Arrays.asList(

View file

@ -34,7 +34,14 @@ public abstract class ElementListConfigGui< T > 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<OutlinePane> pages;
protected HashMap<UUID, Integer> 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();

View file

@ -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(

View file

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

View file

@ -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());

View file

@ -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<String, DoubleSettingGui.DoubleSettingFactory> 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<String, Do
player.sendMessage("\u00A7cThis item can't be damaged, so it can't be repaired.");
return;
}
if(type == this.material){
if(type == this.parentMaterial){
player.sendMessage("\u00A7cItem can't repair something of the same type.");
return;
}
@ -82,7 +83,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
String materialName = type.name().toLowerCase();
// Add new material
ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(material.name().toLowerCase()+"."+materialName,0.25);
ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.name().toLowerCase()+"."+materialName,0.25);
MetricsUtil.INSTANCE.notifyChange(ConfigHolder.UNIT_REPAIR_HOLDER, "");
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
@ -91,7 +92,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
// Update gui
updateValueForGeneric(materialName, true);
this.parentGui.updateValueForGeneric(this.material, true);
this.parentGui.updateValueForGeneric(this.parentMaterial, true);
// Display material edit setting
@ -110,11 +111,17 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
@Override
protected DoubleSettingGui.DoubleSettingFactory createFactory(String materialName) {
String materialDisplayName = CasedStringUtil.snakeToUpperSpacedCase(materialName);
return DoubleSettingGui.doubleFactory(
"\u00A70%\u00A78" +CasedStringUtil.snakeToUpperSpacedCase(materialName)+" Repair",
"\u00A70%\u00A78" + materialDisplayName +" Repair",
this,
material.name().toLowerCase()+"."+materialName,
this.parentMaterial.name().toLowerCase()+"."+materialName,
ConfigHolder.UNIT_REPAIR_HOLDER,
Arrays.asList(
"\u00A77Click here to change how many \u00A7e% \u00A77of \u00A7a" + materialDisplayName,
"\u00A77Should get repaired by \u00A7e"+this.materialName
),
2,
true, true,
0,
@ -137,7 +144,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
return keys;
}
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(material.name().toLowerCase());
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(parentMaterial.name().toLowerCase());
if(materialSection == null){
return keys;
}
@ -154,7 +161,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
@Override
public void updateGuiValues() {
super.updateGuiValues();
this.parentGui.updateValueForGeneric(this.material, true);
this.parentGui.updateValueForGeneric(this.parentMaterial, true);
}
// ElementMappedToListGui methods

View file

@ -66,6 +66,7 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
// Delete item
ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA);
ItemMeta deleteMeta = deleteItem.getItemMeta();
assert deleteMeta != null;
deleteMeta.setDisplayName("\u00A74DELETE RECIPE");
deleteMeta.setLore(Collections.singletonList("\u00A7cCaution with this button !"));
@ -78,24 +79,31 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE();
this.exactCountFactory = BoolSettingsGui.boolFactory("\u00A78Exact count ?", this,
this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_EXACT_COUNT_CONFIG());
AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG);
this.xpCostFactory = IntSettingsGui.intFactory("\u00A78Recipe Xp Cost", this,
this.anvilRecipe +"."+AnvilCustomRecipe.XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.Companion.getDEFAULT_XP_COST_CONFIG(), 1, 5, 10);
null,
costRange.getFirst(), costRange.getLast(), AnvilCustomRecipe.DEFAULT_XP_COST_CONFIG, 1, 5, 10);
this.leftItemFactory = ItemSettingGui.itemFactory("\u00A7eRecipe Left \u00A78Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.LEFT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG());
AnvilCustomRecipe.Companion.getDEFAULT_LEFT_ITEM_CONFIG(),
"\u00A77Set the left item of the custom craft",
"\u00A77\u25A0 + \u25A1 = \u25A1");
this.rightItemFactory = ItemSettingGui.itemFactory("\u00A7eRecipe Right \u00A78Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.RIGHT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG());
AnvilCustomRecipe.Companion.getDEFAULT_RIGHT_ITEM_CONFIG(),
"\u00A77Set the right item of the custom craft",
"\u00A77\u25A1 + \u25A0 = \u25A1");
this.resultItemFactory = ItemSettingGui.itemFactory("\u00A7aRecipe Result \u00A78Item", this,
this.anvilRecipe + "." + AnvilCustomRecipe.RESULT_ITEM_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG());
AnvilCustomRecipe.Companion.getDEFAULT_RESULT_ITEM_CONFIG(),
"\u00A77Set the result item of the custom craft",
"\u00A77\u25A1 + \u25A1 = \u25A0");
}
private ConfirmActionGui createDeleteGui() {
@ -141,19 +149,19 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
public void updateLocal() {
if (!this.shouldWork) return;
GuiItem exactCountItem = GuiGlobalItems.boolSettingGuiItem(this.exactCountFactory);
GuiItem exactCountItem = this.exactCountFactory.getItem();
this.pane.bindItem('1', exactCountItem);
GuiItem xpCostItem = GuiGlobalItems.intSettingGuiItem(this.xpCostFactory, Material.EXPERIENCE_BOTTLE);
GuiItem xpCostItem = this.xpCostFactory.getItem(Material.EXPERIENCE_BOTTLE);
this.pane.bindItem('2', xpCostItem);
GuiItem leftGuiItem = GuiGlobalItems.itemSettingGuiItem(this.leftItemFactory);
GuiItem leftGuiItem = this.leftItemFactory.getItem();
this.pane.bindItem('3', leftGuiItem);
GuiItem rightGuiItem = GuiGlobalItems.itemSettingGuiItem(this.rightItemFactory);
GuiItem rightGuiItem = this.rightItemFactory.getItem();
this.pane.bindItem('4', rightGuiItem);
GuiItem resultGuiItem = GuiGlobalItems.itemSettingGuiItem(this.resultItemFactory);
GuiItem resultGuiItem = this.resultItemFactory.getItem();
this.pane.bindItem('5', resultGuiItem);
update();

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.gui.config.list;
package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;

View file

@ -26,10 +26,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.*;
import java.util.function.Supplier;
import java.util.logging.Level;
@ -73,6 +70,7 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
// Delete item
ItemStack deleteItem = new ItemStack(Material.RED_TERRACOTTA);
ItemMeta deleteMeta = deleteItem.getItemMeta();
assert deleteMeta != null;
deleteMeta.setDisplayName("\u00A74DELETE CONFLICT");
deleteMeta.setLore(Collections.singletonList("\u00A7cCaution with this button !"));
@ -81,7 +79,6 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance));
// Displayed item will be updated later
this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), (event) -> {
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<String> groupLore = new ArrayList<>();
groupLore.add("\u00A77Allow you to select a list of \u00A73Groups \u00A77that this conflict should include");
Set<AbstractMaterialGroup> 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<AbstractMaterialGroup> 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<String> 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);

View file

@ -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<InventoryClickEvent> 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<Boolean> 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<String> 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<String> getUsedLocations(AbstractMaterialGroup group){
ArrayList<String> 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<String> matLore = SelectMaterialContainer.getMaterialLore(this, "group", "include");
// Prepare group lore
List<String> 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<AbstractMaterialGroup> getSelectedGroups() {
return this.group.getGroups();
}
@Override
public boolean setSelectedGroups(Set<AbstractMaterialGroup> 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<AbstractMaterialGroup> 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<AbstractMaterialGroup> illegalGroups() {
Set<AbstractMaterialGroup> 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<Material> getSelectedMaterials() {
return this.group.getNonGroupInheritedMaterials();
}
@Override
public boolean setSelectedMaterials(EnumSet<Material> 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<Material> illegalMaterials() {
return EnumSet.of(Material.AIR);
}
// ----------------------------
// End of SelectGroupContainer related methods
// ----------------------------
private void updateDirectReferencingGroups(AbstractMaterialGroup referenceTo){
Collection<AbstractMaterialGroup> everyStoredGroups = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values();
List<EnchantConflictGroup> everyConflicts = ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList();
HashSet<AbstractMaterialGroup> toUpdate = new HashSet<>();
HashSet<AbstractMaterialGroup> updateFuture = new HashSet<>();
HashSet<AbstractMaterialGroup> conflictGroupPlanned = new HashSet<>();
updateFuture.add(referenceTo);
while (!updateFuture.isEmpty()){
HashSet<AbstractMaterialGroup> 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();
}
}
}

View file

@ -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 {

View file

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

View file

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

View file

@ -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<String> 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<String> 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<String> 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<String> 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){

View file

@ -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<String> 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<String> 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<String> getDisplayLore() {
return this.displayLore;
}
}
}

View file

@ -69,7 +69,7 @@ public class GroupSelectSettingGui extends AbstractSettingGui {
Set<AbstractMaterialGroup> 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);
}

View file

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

View file

@ -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<InventoryClickEvent> setItemAsCursor() { //TODO redo consumer
protected Consumer<InventoryClickEvent> 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<String> 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<String> 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));
}
}
}

View file

@ -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<Material, GuiItem> {
private final SelectMaterialContainer selector;
private final Gui backGui;
private boolean instantRemove;
private final List<Material> defaultMaterials;
private final EnumSet<Material> 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<Material> 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<InventoryClickEvent> 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<Material> 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<Material> 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<String> prepareCreateItemConsumer(HumanEntity player) {// Not used
return null;
}
@Override
protected String genericDisplayedName() {// Not Used
return null;
}
}

View file

@ -97,6 +97,7 @@ public class GuiGlobalActions {
*/
public static @NotNull Consumer<InventoryClickEvent> 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);
};
}

View file

@ -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<String> displayLore,
boolean displayValuePrefix
) {
// Prepare lore
ArrayList<String> 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."));

View file

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

View file

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

View file

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

View file

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

View file

@ -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<Material> {
return groupItems
}

View file

@ -45,7 +45,15 @@ class IncludeGroup(name: String) : AbstractMaterialGroup(name) {
override fun setNonGroupInheritedMaterials(materials: EnumSet<Material>) {
super.setNonGroupInheritedMaterials(materials)
// Update group items
updateMaterials()
}
override fun getGroups(): MutableSet<AbstractMaterialGroup> {
return includedGroup
}
override fun updateMaterials() {
groupItems.clear()
groupItems.addAll(includedMaterial)
@ -54,10 +62,6 @@ class IncludeGroup(name: String) : AbstractMaterialGroup(name) {
}
}
override fun getGroups(): MutableSet<AbstractMaterialGroup> {
return includedGroup
}
override fun getMaterials(): EnumSet<Material> {
return groupItems
}

View file

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

View file

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

View file

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

View file

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