Enchant squared compatibility. (#12)

Allow Custom Anvil to be compatible with [Enchants
Squared](https://www.spigotmc.org/resources/enchants-squared-the-enchantsplus-rewrite-custom-enchantments-that-act-like-vanilla-ones.86747/)

Also extend enchantment list menu to have multiple pages and Add a "see only select" button for select enchantment gui.
This commit is contained in:
alexcrea 2024-06-18 18:57:26 +00:00 committed by GitHub
commit 427b786ad5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 720 additions and 226 deletions

View file

@ -4,7 +4,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.4.8" version = "1.5.0-beta"
repositories { repositories {
mavenCentral() mavenCentral()
@ -26,6 +26,9 @@ dependencies {
// Protocolib // Protocolib
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0") compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
// EnchantsSquaredRewritten
compileOnly(files("libs/EnchantsSquared.jar"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.0") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# All anvil cost will be capped to limit_repair_value if enabled. # All anvil cost will be capped to limit_repair_value if enabled.
# #
# In other words: # In other words:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# material conflicts # material conflicts
# #
# If you want to edit this file: # If you want to edit this file:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Please note this config use spigot material names. # Please note this config use spigot material names.
# It should match minecraft name in most case, maybe every case, but I can't be sure # It should match minecraft name in most case, maybe every case, but I can't be sure
# In case there an issue with material name, you can found them here: # In case there an issue with material name, you can found them here:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Unit repair configuration # Unit repair configuration
# #
# This configuration is to make custom unit repair # This configuration is to make custom unit repair

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# All anvil cost will be capped to limit_repair_value if enabled. # All anvil cost will be capped to limit_repair_value if enabled.
# #
# In other words: # In other words:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# material conflicts # material conflicts
# #
# If you want to edit this file: # If you want to edit this file:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Please note this config use spigot material names. # Please note this config use spigot material names.
# It should match minecraft name in most case, maybe every case, but I can't be sure # It should match minecraft name in most case, maybe every case, but I can't be sure
# In case there an issue with material name, you can found them here: # In case there an issue with material name, you can found them here:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Unit repair configuration # Unit repair configuration
# #
# This configuration is to make custom unit repair # This configuration is to make custom unit repair

BIN
libs/EnchantsSquared.jar Normal file

Binary file not shown.

View file

@ -4,12 +4,15 @@ import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ItemUtil; import io.delilaheve.util.ItemUtil;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta; import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.enchant.wrapped.VanillaEnchant; import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.dependency.EnchantmentSquaredDependency;
import xyz.alexcrea.cuanvil.enchant.wrapped.VanillaEnchantment;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
@ -34,7 +37,7 @@ public abstract class WrappedEnchantment {
* @param defaultRarity Default rarity the enchantment should be. * @param defaultRarity Default rarity the enchantment should be.
* @param defaultMaxLevel Default max level the enchantment can be applied with. * @param defaultMaxLevel Default max level the enchantment can be applied with.
*/ */
public WrappedEnchantment( protected WrappedEnchantment(
@NotNull NamespacedKey key, @NotNull NamespacedKey key,
@Nullable EnchantmentRarity defaultRarity, @Nullable EnchantmentRarity defaultRarity,
int defaultMaxLevel){ int defaultMaxLevel){
@ -50,6 +53,7 @@ public abstract class WrappedEnchantment {
* Get the default rarity of this enchant. * Get the default rarity of this enchant.
* @return The default rarity of this enchant. * @return The default rarity of this enchant.
*/ */
@NotNull
public final EnchantmentRarity defaultRarity(){ public final EnchantmentRarity defaultRarity(){
return defaultRarity; return defaultRarity;
} }
@ -79,13 +83,22 @@ public abstract class WrappedEnchantment {
public final int defaultMaxLevel(){return defaultMaxLevel;} public final int defaultMaxLevel(){return defaultMaxLevel;}
/** /**
* If the enchantment have specialised group operation. * Check if the enchantment have specialised group operation.
* @return If the enchantment is optimised for group operation. * @return If the enchantment is optimised for group operation.
*/ */
protected boolean isOptimised(){ protected boolean isOptimised(){
return false; return false;
} }
/**
* Check if the player is allowed to use this enchantment.
* @param player The player to test.
* @return If the player is allowed to use this enchantment.
*/
public boolean isAllowed(@NotNull HumanEntity player){
return true;
}
/** /**
* Get current level of the enchantment. * Get current level of the enchantment.
* @param item Item to search the level for. * @param item Item to search the level for.
@ -137,7 +150,6 @@ public abstract class WrappedEnchantment {
public abstract void removeFrom(@NotNull ItemStack item); public abstract void removeFrom(@NotNull ItemStack item);
// Static functions // Static functions
/** /**
* Clear every enchantment from this item. * Clear every enchantment from this item.
* @param item Item to be cleared from enchantments. * @param item Item to be cleared from enchantments.
@ -158,6 +170,12 @@ public abstract class WrappedEnchantment {
); );
} }
// Clean Enchant Squared enchants
EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility();
if(enchantmentSquared != null){
enchantmentSquared.clearEnchantments(item);
}
// Clean unoptimised enchants // Clean unoptimised enchants
for (WrappedEnchantment enchant : unoptimisedValues()) { for (WrappedEnchantment enchant : unoptimisedValues()) {
if(enchant.isEnchantmentPresent(item)){ if(enchant.isEnchantmentPresent(item)){
@ -172,7 +190,7 @@ public abstract class WrappedEnchantment {
* @param item Item to get enchantment from. * @param item Item to get enchantment from.
* @return A map of the set enchantments and there's respective levels. * @return A map of the set enchantments and there's respective levels.
*/ */
public static Map<WrappedEnchantment, Integer> getEnchants(@NotNull ItemStack item){ //TODO faster method to find vanilla enchantment public static Map<WrappedEnchantment, Integer> getEnchants(@NotNull ItemStack item){
Map<WrappedEnchantment, Integer> enchantments = new HashMap<>(); Map<WrappedEnchantment, Integer> enchantments = new HashMap<>();
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -189,6 +207,12 @@ public abstract class WrappedEnchantment {
); );
} }
// Enchants Squared get
EnchantmentSquaredDependency enchantmentSquared = DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility();
if(enchantmentSquared != null){
enchantmentSquared.getEnchantmentsSquared(item, enchantments);
}
// Unoptimised enchantment get // Unoptimised enchantment get
findEnchantsFromSelectedList(item, meta, enchantments, unoptimisedValues()); findEnchantsFromSelectedList(item, meta, enchantments, unoptimisedValues());
@ -229,7 +253,11 @@ public abstract class WrappedEnchantment {
*/ */
public static void registerEnchantments(){ public static void registerEnchantments(){
for (Enchantment enchantment : Enchantment.values()) { for (Enchantment enchantment : Enchantment.values()) {
register(new VanillaEnchant(enchantment)); register(new VanillaEnchantment(enchantment));
}
if(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility() != null){
DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility().registerEnchantments();
} }
} }

View file

@ -0,0 +1,67 @@
package xyz.alexcrea.cuanvil.enchant.wrapped;
import me.athlaeos.enchantssquared.enchantments.CustomEnchant;
import me.athlaeos.enchantssquared.managers.CustomEnchantManager;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.enchant.EnchantmentRarity;
import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment;
import java.util.Map;
import java.util.Objects;
public class EnchantSquaredEnchantment extends WrappedEnchantment {
public final @NotNull CustomEnchant enchant;
public EnchantSquaredEnchantment(@NotNull CustomEnchant enchant) {
super(Objects.requireNonNull(
Objects.requireNonNull(DependencyManager.INSTANCE.getEnchantmentSquaredCompatibility()).getKeyFromEnchant(enchant)),
EnchantmentRarity.COMMON,
enchant.getMaxLevel());
this.enchant = enchant;
}
@Override
protected boolean isOptimised() {
return true;
}
@Override
public boolean isAllowed(@NotNull HumanEntity human) {
if(human instanceof Player){
return this.enchant.hasPermission((Player) human);
}
// Not really ideal for maintainability but will probably never be executed. (At least I hope)
boolean required = CustomEnchantManager.getInstance().isRequirePermissions();
if (!required) return true;
return human.hasPermission("es.enchant.*") || !human.hasPermission(this.enchant.getRequiredPermission());
}
@Override
public int getLevel(@NotNull ItemStack item, @NotNull ItemMeta meta) {
return CustomEnchantManager.getInstance().getEnchantStrength(item, this.enchant.getType());
}
@Override
public boolean isEnchantmentPresent(@NotNull ItemStack item, @NotNull ItemMeta meta) {
Map<CustomEnchant, Integer> enchants = CustomEnchantManager.getInstance().getItemsEnchantsFromPDC(item);
return enchants.containsKey(this.enchant);
}
@Override
public void addEnchantmentUnsafe(@NotNull ItemStack item, int level) {
CustomEnchantManager.getInstance().addEnchant(item, this.enchant.getType(), level);
}
@Override
public void removeFrom(@NotNull ItemStack item) {
CustomEnchantManager.getInstance().removeEnchant(item, this.enchant.getType());
}
}

View file

@ -12,11 +12,11 @@ import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment;
import java.util.Locale; import java.util.Locale;
public class VanillaEnchant extends WrappedEnchantment { public class VanillaEnchantment extends WrappedEnchantment {
private final @NotNull Enchantment enchantment; private final @NotNull Enchantment enchantment;
public VanillaEnchant(@NotNull Enchantment enchantment){ public VanillaEnchantment(@NotNull Enchantment enchantment){
super(enchantment.getKey(), super(enchantment.getKey(),
getRarity(enchantment), getRarity(enchantment),
enchantment.getMaxLevel()); enchantment.getMaxLevel());
@ -78,10 +78,11 @@ public class VanillaEnchant extends WrappedEnchantment {
} }
public static EnchantmentRarity getRarity(Enchantment enchantment){ public static EnchantmentRarity getRarity(Enchantment enchantment){
try {return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();} try {
catch (IllegalArgumentException ignored) {} return EnchantmentProperties.valueOf(enchantment.getKey().getKey().toUpperCase(Locale.ENGLISH)).getRarity();
} catch (IllegalArgumentException ignored) {
return EnchantmentRarity.COMMON; return EnchantmentRarity.COMMON;
} }
}
} }

View file

@ -1,20 +1,11 @@
package xyz.alexcrea.cuanvil.gui; package xyz.alexcrea.cuanvil.gui;
import com.github.stefvanschie.inventoryframework.adventuresupport.TextHolder; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public abstract class ValueUpdatableGui extends ChestGui { public interface ValueUpdatableGui {
public ValueUpdatableGui(int rows, @NotNull String title, @NotNull Plugin plugin) { void updateGuiValues();
super(rows, title, plugin);
}
public ValueUpdatableGui(int rows, @NotNull TextHolder title, @NotNull Plugin plugin) { Gui getConnectedGui();
super(rows, title, plugin);
}
public abstract void updateGuiValues();
} }

View file

@ -8,9 +8,9 @@ import io.delilaheve.CustomAnvil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager;
import xyz.alexcrea.cuanvil.gui.config.global.*; import xyz.alexcrea.cuanvil.gui.config.global.*;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.packet.PacketManager;
import java.util.Collections; import java.util.Collections;

View file

@ -1,23 +1,25 @@
package xyz.alexcrea.cuanvil.gui.config.global; package xyz.alexcrea.cuanvil.gui.config.global;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.pane.Orientable; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import com.github.stefvanschie.inventoryframework.pane.OutlinePane; import org.bukkit.event.inventory.InventoryClickEvent;
import io.delilaheve.CustomAnvil;
import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment; import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.ArrayList; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
/** /**
* Abstract Global Config gui for enchantment setting configuration. * Abstract Global Config gui for enchantment setting configuration.
* *
* @param <T> Type of the factory of the type of setting the gui should edit. * @param <T> Type of the factory of the type of setting the gui should edit.
*/ */
public abstract class AbstractEnchantConfigGui<T extends AbstractSettingGui.SettingGuiFactory> extends ValueUpdatableGui { public abstract class AbstractEnchantConfigGui<T extends SettingGui.SettingGuiFactory> extends SettingGuiListConfigGui<WrappedEnchantment, T> implements ValueUpdatableGui {
/** /**
* Constructor for a gui displaying available enchantment to edit a enchantment setting. * Constructor for a gui displaying available enchantment to edit a enchantment setting.
@ -25,63 +27,50 @@ public abstract class AbstractEnchantConfigGui<T extends AbstractSettingGui.Sett
* @param title Title of the gui. * @param title Title of the gui.
*/ */
protected AbstractEnchantConfigGui(String title) { protected AbstractEnchantConfigGui(String title) {
super(6, title, CustomAnvil.instance); super(title);
}
private OutlinePane filledEnchant;
/**
* Initialise value updatable gui pattern
*/
protected void init() {
// Back item panel
addPane(GuiSharedConstant.BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE);
// enchant item panel
this.filledEnchant = new OutlinePane(0, 0, 9, 5);
this.filledEnchant.align(OutlinePane.Alignment.BEGIN);
this.filledEnchant.setOrientation(Orientable.Orientation.HORIZONTAL);
addPane(this.filledEnchant);
prepareValues();
updateGuiValues();
}
private List<T> bookItemFactoryList;
/**
* Prepare enchantment config gui displayed items factory.
*/
protected void prepareValues() {
bookItemFactoryList = new ArrayList<>();
for (WrappedEnchantment enchant : GuiSharedConstant.SORTED_ENCHANTMENT_LIST) {
T factory = getFactoryFromEnchant(enchant);
bookItemFactoryList.add(factory);
}
} }
@Override @Override
public void updateGuiValues() { public void updateGuiValues() { //TODO maybe optimise it.
reloadValues();
// probably not the most efficient but hey ! it do the work
// TODO optimise one day.. maybe
this.filledEnchant.clear();
for (T inventoryFactory : this.bookItemFactoryList) {
GuiItem item = getItemFromFactory(inventoryFactory);
this.filledEnchant.addItem(item);
} }
update(); @Override
protected Collection<WrappedEnchantment> getEveryDisplayableInstanceOfGeneric() {
return GuiSharedConstant.SORTED_ENCHANTMENT_LIST;
}
@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,
"B11L1R111"
);
} }
public abstract T getFactoryFromEnchant(WrappedEnchantment enchant); // Unused methods
@Override
protected GuiItem prepareCreateNewItem() {
return null;
}
public abstract GuiItem getItemFromFactory(T inventoryFactory); @Override
protected List<String> getCreateItemLore() {
return Collections.emptyList();
}
@Override
protected Consumer<InventoryClickEvent> getCreateClickConsumer() {
return null;
}
@Override
protected String createItemName() {
return null;
}
} }

View file

@ -1,6 +1,8 @@
package xyz.alexcrea.cuanvil.gui.config.global; package xyz.alexcrea.cuanvil.gui.config.global;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -11,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui; import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui; import xyz.alexcrea.cuanvil.gui.config.settings.BoolSettingsGui;
@ -18,7 +21,6 @@ import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.packet.PacketManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -27,7 +29,7 @@ import java.util.Collections;
/** /**
* Global config to edit basic basic settings. * Global config to edit basic basic settings.
*/ */
public class BasicConfigGui extends ValueUpdatableGui { public class BasicConfigGui extends ChestGui implements ValueUpdatableGui {
private static BasicConfigGui INSTANCE; private static BasicConfigGui INSTANCE;
@ -253,4 +255,9 @@ public class BasicConfigGui extends ValueUpdatableGui {
update(); update();
} }
@Override
public Gui getConnectedGui() {
return this;
}
} }

View file

@ -12,6 +12,7 @@ import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> { public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRecipe, CustomRecipeSubSettingGui> {
@ -90,7 +91,7 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui<AnvilCustomRec
@Override @Override
protected List<AnvilCustomRecipe> getEveryDisplayableInstanceOfGeneric() { protected Collection<AnvilCustomRecipe> getEveryDisplayableInstanceOfGeneric() {
return ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().getRecipeList(); return ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().getRecipeList();
} }
} }

View file

@ -14,6 +14,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> { public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGroup, EnchantConflictSubSettingGui> {
@ -83,7 +84,7 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
} }
@Override @Override
protected List<EnchantConflictGroup> getEveryDisplayableInstanceOfGeneric() { protected Collection<EnchantConflictGroup> getEveryDisplayableInstanceOfGeneric() {
return ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList(); return ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList();
} }

View file

@ -12,19 +12,16 @@ import xyz.alexcrea.cuanvil.gui.config.settings.EnchantCostSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
/** /**
* Global Config gui for enchantment cost settings. * Global Config gui for enchantment cost settings.
*/ */
public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSettingsGui.EnchantCostSettingFactory> { public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSettingsGui.EnchantCostSettingFactory> {
private final static String SECTION_NAME = "enchant_values"; private static final String SECTION_NAME = "enchant_values";
public final static EnchantCostConfigGui INSTANCE = new EnchantCostConfigGui(); public static final EnchantCostConfigGui INSTANCE = new EnchantCostConfigGui();
static { static {
INSTANCE.init(); INSTANCE.init();
@ -39,7 +36,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
} }
@Override @Override
public EnchantCostSettingsGui.EnchantCostSettingFactory getFactoryFromEnchant(WrappedEnchantment enchant) { public EnchantCostSettingsGui.EnchantCostSettingFactory createFactory(WrappedEnchantment enchant) {
String key = enchant.getKey().getKey().toLowerCase(Locale.ENGLISH); String key = enchant.getKey().getKey().toLowerCase(Locale.ENGLISH);
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key); String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key);
@ -62,7 +59,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
} }
@Override @Override
public GuiItem getItemFromFactory(EnchantCostSettingsGui.EnchantCostSettingFactory factory) { public GuiItem itemFromFactory(WrappedEnchantment enchantment, EnchantCostSettingsGui.EnchantCostSettingFactory factory) {
// Get item properties // Get item properties
int itemCost = factory.getConfiguredValue(); int itemCost = factory.getConfiguredValue();
int bookCost = factory.getConfiguredBookValue(); int bookCost = factory.getConfiguredBookValue();

View file

@ -15,9 +15,9 @@ import java.util.Locale;
*/ */
public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsGui.IntSettingFactory> { public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsGui.IntSettingFactory> {
private final static String SECTION_NAME = "enchant_limits"; private static final String SECTION_NAME = "enchant_limits";
public final static EnchantLimitConfigGui INSTANCE = new EnchantLimitConfigGui(); public static final EnchantLimitConfigGui INSTANCE = new EnchantLimitConfigGui();
static { static {
INSTANCE.init(); INSTANCE.init();
@ -32,7 +32,7 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
} }
@Override @Override
public IntSettingsGui.IntSettingFactory getFactoryFromEnchant(WrappedEnchantment enchant) { public IntSettingsGui.IntSettingFactory createFactory(WrappedEnchantment enchant) {
String key = enchant.getKey().getKey().toLowerCase(Locale.ROOT); String key = enchant.getKey().getKey().toLowerCase(Locale.ROOT);
String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key); String prettyKey = CasedStringUtil.snakeToUpperSpacedCase(key);
@ -47,7 +47,7 @@ public class EnchantLimitConfigGui extends AbstractEnchantConfigGui<IntSettingsG
} }
@Override @Override
public GuiItem getItemFromFactory(IntSettingsGui.IntSettingFactory inventoryFactory) { public GuiItem itemFromFactory(WrappedEnchantment enchantment, IntSettingsGui.IntSettingFactory inventoryFactory) {
return inventoryFactory.getItem( return inventoryFactory.getItem(
Material.ENCHANTED_BOOK, Material.ENCHANTED_BOOK,
inventoryFactory.getTitle()); inventoryFactory.getTitle());

View file

@ -16,6 +16,7 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupConfigSubSettingGui> { public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupConfigSubSettingGui> {
@ -49,7 +50,7 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupCo
} }
@Override @Override
protected List<IncludeGroup> getEveryDisplayableInstanceOfGeneric() { protected Collection<IncludeGroup> getEveryDisplayableInstanceOfGeneric() {
ArrayList<IncludeGroup> includeGroups = new ArrayList<>(); ArrayList<IncludeGroup> includeGroups = new ArrayList<>();
for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) { for (AbstractMaterialGroup group : ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager().getGroupMap().values()) {

View file

@ -14,11 +14,12 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRepairElementListGui> { public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRepairElementListGui> {
public final static UnitRepairConfigGui INSTANCE = new UnitRepairConfigGui(); public static final UnitRepairConfigGui INSTANCE = new UnitRepairConfigGui();
static { static {
INSTANCE.init(); INSTANCE.init();
@ -62,7 +63,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
} }
@Override @Override
protected List<Material> getEveryDisplayableInstanceOfGeneric() { protected Collection<Material> getEveryDisplayableInstanceOfGeneric() {
ArrayList<Material> materials = new ArrayList<>(); ArrayList<Material> materials = new ArrayList<>();
for (String matName : ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getKeys(false)) { for (String matName : ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getKeys(false)) {
@ -89,7 +90,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
createItem.setItemMeta(createMeta); createItem.setItemMeta(createMeta);
return new GuiItem(createItem, (clickEvent) -> { return new GuiItem(createItem, clickEvent -> {
clickEvent.setCancelled(true); clickEvent.setCancelled(true);
new SelectItemTypeGui( new SelectItemTypeGui(

View file

@ -1,6 +1,8 @@
package xyz.alexcrea.cuanvil.gui.config.list; package xyz.alexcrea.cuanvil.gui.config.list;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.Orientable; import com.github.stefvanschie.inventoryframework.pane.Orientable;
import com.github.stefvanschie.inventoryframework.pane.OutlinePane; import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
import com.github.stefvanschie.inventoryframework.pane.Pane; import com.github.stefvanschie.inventoryframework.pane.Pane;
@ -18,18 +20,15 @@ import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public abstract class ElementListConfigGui< T > extends ValueUpdatableGui { public abstract class ElementListConfigGui< T > extends ChestGui implements ValueUpdatableGui {
private final String namePrefix; private final String namePrefix;
protected PatternPane backgroundPane; protected PatternPane backgroundPane;
public ElementListConfigGui(@NotNull String title) { protected ElementListConfigGui(@NotNull String title) {
super(6, title, CustomAnvil.instance); super(6, title, CustomAnvil.instance);
this.namePrefix = title; this.namePrefix = title;
@ -55,7 +54,7 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui {
protected ArrayList<OutlinePane> pages; protected ArrayList<OutlinePane> pages;
protected HashMap<UUID, Integer> pageMap; protected HashMap<UUID, Integer> pageMap;
public void init() { // Why I'm using an init function ? public void init() { // Why I'm using an init function ? //TODO determine why is it using a init function and not used on constructor.
GuiGlobalItems.addBackgroundItem(this.backgroundPane); GuiGlobalItems.addBackgroundItem(this.backgroundPane);
this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM); this.backgroundPane.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);
addPane(this.backgroundPane); addPane(this.backgroundPane);
@ -294,7 +293,7 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui {
protected abstract void updateGeneric(T generic, ItemStack usedItem); protected abstract void updateGeneric(T generic, ItemStack usedItem);
protected abstract List<T> getEveryDisplayableInstanceOfGeneric(); protected abstract Collection<T> getEveryDisplayableInstanceOfGeneric();
@Override @Override
public void updateGuiValues() { public void updateGuiValues() {
@ -304,4 +303,9 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui {
reloadValues(); reloadValues();
} }
@Override
public Gui getConnectedGui() {
return this;
}
} }

View file

@ -16,7 +16,7 @@ import java.util.function.Consumer;
public abstract class MappedElementListConfigGui< T, S > extends ElementListConfigGui< T > { public abstract class MappedElementListConfigGui< T, S > extends ElementListConfigGui< T > {
protected final HashMap<T, S> elementGuiMap; protected final HashMap<T, S> elementGuiMap;
public MappedElementListConfigGui(@NotNull String title) { protected MappedElementListConfigGui(@NotNull String title) {
super(title); super(title);
this.elementGuiMap = new HashMap<>(); this.elementGuiMap = new HashMap<>();
@ -38,7 +38,7 @@ public abstract class MappedElementListConfigGui< T, S > extends ElementListConf
createItem.setItemMeta(createMeta); createItem.setItemMeta(createMeta);
return new GuiItem(createItem, (clickEvent) -> { return new GuiItem(createItem, clickEvent -> {
clickEvent.setCancelled(true); clickEvent.setCancelled(true);
HumanEntity player = clickEvent.getWhoClicked(); HumanEntity player = clickEvent.getWhoClicked();

View file

@ -7,17 +7,17 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class SettingGuiListConfigGui< T, S extends AbstractSettingGui.SettingGuiFactory> extends ElementListConfigGui< T >{ public abstract class SettingGuiListConfigGui< T, S extends SettingGui.SettingGuiFactory> extends ElementListConfigGui< T >{
protected HashMap<T, GuiItem> guiItemMap; protected HashMap<T, GuiItem> guiItemMap;
protected HashMap<T, S> factoryMap; protected HashMap<T, S> factoryMap;
public SettingGuiListConfigGui(@NotNull String title) { protected SettingGuiListConfigGui(@NotNull String title) {
super(title); super(title);
this.guiItemMap = new HashMap<>(); this.guiItemMap = new HashMap<>();
this.factoryMap = new HashMap<>(); this.factoryMap = new HashMap<>();
@ -38,16 +38,16 @@ public abstract class SettingGuiListConfigGui< T, S extends AbstractSettingGui.S
@Override @Override
public void updateValueForGeneric(T generic, boolean shouldUpdate) { public void updateValueForGeneric(T generic, boolean shouldUpdate) {
S factory = this.factoryMap.get(generic); if(!this.factoryMap.containsKey(generic)){
if(factory == null){
// Create new item & factory // Create new item & factory
factory = createFactory(generic); S factory = createFactory(generic);
GuiItem newItem = itemFromFactory(generic, factory); GuiItem newItem = itemFromFactory(generic, factory);
addToPage(newItem); addToPage(newItem);
this.guiItemMap.put(generic, newItem); this.guiItemMap.put(generic, newItem);
this.factoryMap.put(generic, factory); this.factoryMap.put(generic, factory);
}else{ }else{
S factory = this.factoryMap.get(generic);
// Update old item // Update old item
GuiItem oldItem = this.guiItemMap.get(generic); GuiItem oldItem = this.guiItemMap.get(generic);
@ -73,6 +73,7 @@ public abstract class SettingGuiListConfigGui< T, S extends AbstractSettingGui.S
oldITem.setProperties(newItem.getProperties()); oldITem.setProperties(newItem.getProperties());
oldITem.setVisible(newItem.isVisible()); oldITem.setVisible(newItem.isVisible());
} }
@Override @Override
protected GuiItem findGuiItemForRemoval(T generic) { protected GuiItem findGuiItemForRemoval(T generic) {
return this.guiItemMap.get(generic); return this.guiItemMap.get(generic);

View file

@ -20,6 +20,7 @@ import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -136,7 +137,7 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
} }
@Override @Override
protected List<String> getEveryDisplayableInstanceOfGeneric() { protected Collection<String> getEveryDisplayableInstanceOfGeneric() {
ArrayList<String> keys = new ArrayList<>(); ArrayList<String> keys = new ArrayList<>();
if(!this.shouldWork){ if(!this.shouldWork){
return keys; return keys;

View file

@ -79,15 +79,15 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance)); this.pane.bindItem('D', new GuiItem(deleteItem, GuiGlobalActions.openGuiAction(createDeleteGui()), CustomAnvil.instance));
// Displayed item will be updated later // Displayed item will be updated later
this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), (event) -> { this.enchantSettingItem = new GuiItem(new ItemStack(Material.ENCHANTED_BOOK), event -> {
event.setCancelled(true); event.setCancelled(true);
EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui( EnchantSelectSettingGui enchantGui = new EnchantSelectSettingGui(
"\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + " \u00A75Enchantments", "\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(enchantConflict.toString()) + "\u00A75",
this, this, 0); this, this);
enchantGui.show(event.getWhoClicked()); enchantGui.show(event.getWhoClicked());
}, CustomAnvil.instance); }, CustomAnvil.instance);
this.groupSettingItem = new GuiItem(new ItemStack(Material.PAPER), (event) -> { this.groupSettingItem = new GuiItem(new ItemStack(Material.PAPER), event -> {
event.setCancelled(true); event.setCancelled(true);
GroupSelectSettingGui enchantGui = new GroupSelectSettingGui( GroupSelectSettingGui enchantGui = new GroupSelectSettingGui(
"\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + " \u00A73Groups", "\u00A7e" + CasedStringUtil.snakeToUpperSpacedCase(this.enchantConflict.toString()) + " \u00A73Groups",

View file

@ -1,15 +1,16 @@
package xyz.alexcrea.cuanvil.gui.config.list.elements; package xyz.alexcrea.cuanvil.gui.config.list.elements;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
public abstract class MappedToListSubSettingGui extends ValueUpdatableGui implements ElementMappedToListGui { public abstract class MappedToListSubSettingGui extends ChestGui implements ValueUpdatableGui, ElementMappedToListGui {
private final GuiItem item; private final GuiItem item;
public MappedToListSubSettingGui( protected MappedToListSubSettingGui(
GuiItem item, GuiItem item,
int rows, int rows,
@NotNull String title) { @NotNull String title) {
@ -27,5 +28,9 @@ public abstract class MappedToListSubSettingGui extends ValueUpdatableGui implem
return this; return this;
} }
@Override
public Gui getConnectedGui() {
return this;
}
} }

View file

@ -15,9 +15,9 @@ import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
/** /**
* An instance gui used to edit a setting. * An instance gui used to edit a setting.
*/ */
public abstract class AbstractSettingGui extends ChestGui { public abstract class AbstractSettingGui extends ChestGui implements SettingGui {
protected final static String CLICK_LORE = "\u00A77Click Here to change the value"; protected static final String CLICK_LORE = "\u00A77Click Here to change the value";
private PatternPane pane; private PatternPane pane;
@ -28,7 +28,7 @@ public abstract class AbstractSettingGui extends ChestGui {
* @param title Title of this gui. * @param title Title of this gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
*/ */
public AbstractSettingGui(int rows, @NotNull TextHolder title, ValueUpdatableGui parent) { protected AbstractSettingGui(int rows, @NotNull TextHolder title, ValueUpdatableGui parent) {
super(rows, title, CustomAnvil.instance); super(rows, title, CustomAnvil.instance);
initBase(parent); initBase(parent);
} }
@ -40,12 +40,11 @@ public abstract class AbstractSettingGui extends ChestGui {
* @param title Title of this gui. * @param title Title of this gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
*/ */
public AbstractSettingGui(int rows, @NotNull String title, ValueUpdatableGui parent) { protected AbstractSettingGui(int rows, @NotNull String title, ValueUpdatableGui parent) {
this(rows, StringHolder.of(title), parent); this(rows, StringHolder.of(title), parent);
} }
protected GuiItem saveItem; protected GuiItem saveItem;
protected GuiItem noChangeItem;
/** /**
* Initialise and prepare value for this gui. * Initialise and prepare value for this gui.
@ -57,19 +56,18 @@ public abstract class AbstractSettingGui extends ChestGui {
pane = new PatternPane(0, 0, pattern.getLength(), pattern.getHeight(), pattern); pane = new PatternPane(0, 0, pattern.getLength(), pattern.getHeight(), pattern);
addPane(pane); addPane(pane);
GuiGlobalItems.addBackItem(pane, parent); GuiGlobalItems.addBackItem(pane, parent.getConnectedGui());
GuiGlobalItems.addBackgroundItem(pane); GuiGlobalItems.addBackgroundItem(pane);
saveItem = GuiGlobalItems.saveItem(this, parent); saveItem = GuiGlobalItems.saveItem(this, parent);
noChangeItem = GuiGlobalItems.noChangeItem();
pane.bindItem('S', noChangeItem); pane.bindItem('S', GuiGlobalItems.noChangeItem());
} }
@Override @Override
public void update() { public void update() {
pane.bindItem('S', hadChange() ? saveItem : noChangeItem); pane.bindItem('S', hadChange() ? saveItem : GuiGlobalItems.noChangeItem());
super.update(); super.update();
} }
@ -95,27 +93,13 @@ public abstract class AbstractSettingGui extends ChestGui {
*/ */
protected abstract Pattern getGuiPattern(); protected abstract Pattern getGuiPattern();
/**
* Called when the associated setting need to be saved.
*
* @return true if the save was successful. false otherwise
*/
public abstract boolean onSave();
/**
* If this function return true
* the gui assume the associated setting can be saved.
*
* @return true if there is a change to the setting. false otherwise
*/
public abstract boolean hadChange();
/** /**
* Most of the time a setting gui will be called from a global gui. * Most of the time a setting gui will be called from a global gui.
* <p> * <p>
* It is better to keep a factory that hold setting data than find what parameters to use every time. * It is better to keep a factory that hold setting data than find what parameters to use every time.
*/ */
public abstract static class SettingGuiFactory { public abstract static class SettingGuiFactory implements SettingGui.SettingGuiFactory {
@NotNull @NotNull
protected String configPath; protected String configPath;
@NotNull @NotNull
@ -148,11 +132,5 @@ public abstract class AbstractSettingGui extends ChestGui {
return config; return config;
} }
/**
* Create a gui using setting parameters and current setting value.
*
* @return A new instance of the implemented setting gui.
*/
public abstract AbstractSettingGui create();
} }
} }

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -233,7 +234,7 @@ public class BoolSettingsGui extends AbstractSettingGui {
} }
@Override @Override
public AbstractSettingGui create() { public Gui create() {
// Get current value or default // Get current value or default
boolean now = getConfiguredValue(); boolean now = getConfiguredValue();
// create new gui // create new gui

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -471,7 +472,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
} }
@Override @Override
public AbstractSettingGui create() { public Gui create() {
// Get value or default // Get value or default
BigDecimal now = getConfiguredValue(); BigDecimal now = getConfiguredValue();
// create new gui // create new gui

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -321,7 +322,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
} }
@Override @Override
public AbstractSettingGui create() { public Gui create() {
// Get value or default // Get value or default
int nowItem = getConfiguredValue(); int nowItem = getConfiguredValue();
// create new gui // create new gui

View file

@ -1,9 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.pane.Orientable; import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
import com.github.stefvanschie.inventoryframework.pane.Pane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.bukkit.Material; import org.bukkit.Material;
@ -13,71 +11,80 @@ import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment; import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer; import xyz.alexcrea.cuanvil.gui.config.SelectEnchantmentContainer;
import xyz.alexcrea.cuanvil.gui.config.list.SettingGuiListConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.util.CasedStringUtil; import xyz.alexcrea.cuanvil.util.CasedStringUtil;
import java.util.Collections; import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class EnchantSelectSettingGui extends AbstractSettingGui { public class EnchantSelectSettingGui extends SettingGuiListConfigGui<WrappedEnchantment, EnchantSelectSettingGui.DummyFactory> implements SettingGui {
SelectEnchantmentContainer enchantContainer; private final SelectEnchantmentContainer enchantContainer;
int page;
Set<WrappedEnchantment> selectedEnchant; private final Set<WrappedEnchantment> selectedEnchant;
private final GuiItem saveItem;
public EnchantSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer, int page) { private boolean displayUnselected;
super(6, title, parent);
public EnchantSelectSettingGui(@NotNull String title, ValueUpdatableGui parent, SelectEnchantmentContainer enchantContainer) {
super(title);
this.enchantContainer = enchantContainer; this.enchantContainer = enchantContainer;
// Not used and not planned rn
this.page = page;
this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments()); this.selectedEnchant = new HashSet<>(enchantContainer.getSelectedEnchantments());
// Add secondary background item this.saveItem = GuiGlobalItems.saveItem(this, parent);
this.getPane().bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM); this.backgroundPane.bindItem('S', GuiGlobalItems.noChangeItem());
initGroups(); this.displayUnselected = true;
this.backgroundPane.bindItem('b', createDisplayUnusedItem());
init();
} }
@Override @Override
protected Pattern getGuiPattern() { protected Pattern getBackgroundPattern() {
return new Pattern( return new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,
"B1111111S" "B11LbR11S"
); );
} }
protected void initGroups() { @Override
// Add enchantment gui item protected Collection<WrappedEnchantment> getEveryDisplayableInstanceOfGeneric() {
OutlinePane filledEnchant = new OutlinePane(0, 0, 9, 5); Stream<WrappedEnchantment> toDisplayStream;
filledEnchant.setPriority(Pane.Priority.HIGH); if(this.displayUnselected){
filledEnchant.align(OutlinePane.Alignment.BEGIN); toDisplayStream = Arrays.stream(WrappedEnchantment.values());
filledEnchant.setOrientation(Orientable.Orientation.HORIZONTAL); }else{
toDisplayStream = this.selectedEnchant.stream();
Set<WrappedEnchantment> illegalEnchant = this.enchantContainer.illegalEnchantments();
for (WrappedEnchantment enchant : GuiSharedConstant.SORTED_ENCHANTMENT_LIST) {
if (illegalEnchant.contains(enchant)) {
return;
} }
filledEnchant.addItem(getGuiItemFromEnchant(enchant)); Set<WrappedEnchantment> illegalEnchantments = this.enchantContainer.illegalEnchantments();
return toDisplayStream
.filter(enchantment -> !illegalEnchantments.contains(enchantment))
.collect(Collectors.toList());
} }
addPane(filledEnchant); @Override
public void update() {
this.backgroundPane.bindItem('S', hadChange() ? saveItem : GuiGlobalItems.noChangeItem());
super.update();
} }
private GuiItem getGuiItemFromEnchant(WrappedEnchantment enchantment) { @Override
protected GuiItem itemFromFactory(WrappedEnchantment enchantment, DummyFactory factory) {
boolean isIn = this.selectedEnchant.contains(enchantment); boolean isIn = this.selectedEnchant.contains(enchantment);
Material usedMaterial; Material usedMaterial;
@ -95,6 +102,27 @@ public class EnchantSelectSettingGui extends AbstractSettingGui {
return guiItem; return guiItem;
} }
private GuiItem createDisplayUnusedItem() {
ItemStack item = new ItemStack(this.displayUnselected ? Material.BOOK : Material.ENCHANTED_BOOK);
ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.setDisplayName((this.displayUnselected ? "\u00A7aEverything displayed" : "\u00A7eOnly selected displayed"));
meta.setLore(Collections.singletonList(
"\u00A77Click here to see " +
(this.displayUnselected ? "only selected" : "every") +
" enchantments"));
item.setItemMeta(meta);
return new GuiItem(item, clickEvent -> {
clickEvent.setCancelled(true);
this.displayUnselected = !this.displayUnselected;
this.backgroundPane.bindItem('b', createDisplayUnusedItem());
reloadValues();
}, CustomAnvil.instance);
}
private static final List<String> TRUE_LORE = Collections.singletonList("\u00A77Value: \u00A7aSelected"); private static final List<String> TRUE_LORE = Collections.singletonList("\u00A77Value: \u00A7aSelected");
private static final List<String> FALSE_LORE = Collections.singletonList("\u00A77Value: \u00A7cNot Selected"); private static final List<String> FALSE_LORE = Collections.singletonList("\u00A77Value: \u00A7cNot Selected");
@ -157,4 +185,32 @@ public class EnchantSelectSettingGui extends AbstractSettingGui {
!baseGroup.containsAll(this.selectedEnchant); !baseGroup.containsAll(this.selectedEnchant);
} }
// Unused methods and class
public static class DummyFactory extends AbstractSettingGui.SettingGuiFactory{
protected DummyFactory(@NotNull String configPath, @NotNull ConfigHolder config) {
super(configPath, config);
}
@Override
public Gui create() {
return null;
}
}
@Override
protected List<String> getCreateItemLore() {
return Collections.emptyList();
}
@Override
protected Consumer<InventoryClickEvent> getCreateClickConsumer() {
return null;
}
@Override
protected String createItemName() {
return null;
}
@Override
protected DummyFactory createFactory(WrappedEnchantment generic) {
return null;
}
} }

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -370,7 +371,7 @@ public class IntSettingsGui extends AbstractSettingGui {
} }
@Override @Override
public AbstractSettingGui create() { public Gui create() {
// Get value or default // Get value or default
int now = getConfiguredValue(); int now = getConfiguredValue();
// create new gui // create new gui

View file

@ -1,6 +1,7 @@
package xyz.alexcrea.cuanvil.gui.config.settings; package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.GuiItem;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
import com.github.stefvanschie.inventoryframework.pane.PatternPane; import com.github.stefvanschie.inventoryframework.pane.PatternPane;
import com.github.stefvanschie.inventoryframework.pane.util.Pattern; import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
@ -240,7 +241,7 @@ public class ItemSettingGui extends AbstractSettingGui {
} }
@Override @Override
public AbstractSettingGui create() { public Gui create() {
// Get current value or default // Get current value or default
ItemStack now = getConfiguredValue(); ItemStack now = getConfiguredValue();
// create new gui // create new gui

View file

@ -216,7 +216,7 @@ public class MaterialSelectSettingGui extends MappedElementListConfigGui<Materia
} }
@Override @Override
protected List<Material> getEveryDisplayableInstanceOfGeneric() { protected Collection<Material> getEveryDisplayableInstanceOfGeneric() {
return this.defaultMaterials; return this.defaultMaterials;
} }

View file

@ -0,0 +1,33 @@
package xyz.alexcrea.cuanvil.gui.config.settings;
import com.github.stefvanschie.inventoryframework.gui.type.util.Gui;
public interface SettingGui {
/**
* Called when the associated setting need to be saved.
*
* @return true if the save was successful. false otherwise
*/
boolean onSave();
/**
* If this function return true
* the gui assume the associated setting can be saved.
*
* @return true if there is a change to the setting. false otherwise
*/
boolean hadChange();
interface SettingGuiFactory {
/**
* Create a gui using setting parameters and current setting value.
*
* @return A new instance of the implemented setting gui.
*/
Gui create();
}
}

View file

@ -7,6 +7,7 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -17,12 +18,12 @@ import java.util.function.Consumer;
*/ */
public class GuiGlobalActions { public class GuiGlobalActions {
public final static String NO_EDIT_PERM = "§cYou do not have permission to edit the config"; public static final String NO_EDIT_PERM = "§cYou do not have permission to edit the config";
/** /**
* A Consumer that should be used if the item goal is to do nothing on click. * A Consumer that should be used if the item goal is to do nothing on click.
*/ */
public final static Consumer<InventoryClickEvent> stayInPlace = (event) -> event.setCancelled(true); public static final Consumer<InventoryClickEvent> stayInPlace = event -> event.setCancelled(true);
/** /**
* Create a consumer to create and open a new GUI. * Create a consumer to create and open a new GUI.
@ -80,7 +81,7 @@ public class GuiGlobalActions {
* @param factory The setting gui factory. * @param factory The setting gui factory.
* @return A consumer to create and open a new setting GUI. * @return A consumer to create and open a new setting GUI.
*/ */
public static @NotNull Consumer<InventoryClickEvent> openSettingGuiAction(AbstractSettingGui.SettingGuiFactory factory) { public static @NotNull Consumer<InventoryClickEvent> openSettingGuiAction(SettingGui.SettingGuiFactory factory) {
return event -> { return event -> {
event.setCancelled(true); event.setCancelled(true);
Gui gui = factory.create(); Gui gui = factory.create();
@ -119,7 +120,7 @@ public class GuiGlobalActions {
* @return A consumer to open a global GUI. * @return A consumer to open a global GUI.
*/ */
public static @NotNull Consumer<InventoryClickEvent> saveSettingAction( public static @NotNull Consumer<InventoryClickEvent> saveSettingAction(
@NotNull AbstractSettingGui setting, @NotNull SettingGui setting,
@NotNull ValueUpdatableGui goal) { @NotNull ValueUpdatableGui goal) {
return event -> { return event -> {
event.setCancelled(true); event.setCancelled(true);
@ -138,7 +139,7 @@ public class GuiGlobalActions {
// Update gui for those who have it open. // Update gui for those who have it open.
goal.updateGuiValues(); goal.updateGuiValues();
// Then show // Then show
goal.show(player); goal.getConnectedGui().show(player);
}; };
} }

View file

@ -12,6 +12,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui; import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.AbstractSettingGui;
import xyz.alexcrea.cuanvil.gui.config.settings.SettingGui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -132,7 +133,7 @@ public class GuiGlobalItems {
* @return A save setting item. * @return A save setting item.
*/ */
public static GuiItem saveItem( public static GuiItem saveItem(
@NotNull AbstractSettingGui setting, @NotNull SettingGui setting,
@NotNull ValueUpdatableGui goal) { @NotNull ValueUpdatableGui goal) {
ItemStack item = new ItemStack(DEFAULT_SAVE_ITEM); ItemStack item = new ItemStack(DEFAULT_SAVE_ITEM);
@ -179,7 +180,7 @@ public class GuiGlobalItems {
*/ */
public static GuiItem openSettingGuiItem( public static GuiItem openSettingGuiItem(
@NotNull ItemStack item, @NotNull ItemStack item,
@NotNull AbstractSettingGui.SettingGuiFactory factory @NotNull SettingGui.SettingGuiFactory factory
) { ) {
return new GuiItem(item, GuiGlobalActions.openSettingGuiAction(factory), CustomAnvil.instance); return new GuiItem(item, GuiGlobalActions.openSettingGuiAction(factory), CustomAnvil.instance);
} }
@ -199,7 +200,7 @@ public class GuiGlobalItems {
* @return A formatted GuiItem that will create and open a GUI for the setting. * @return A formatted GuiItem that will create and open a GUI for the setting.
*/ */
public static GuiItem createGuiItemFromProperties( public static GuiItem createGuiItemFromProperties(
@NotNull AbstractSettingGui.SettingGuiFactory factory, @NotNull SettingGui.SettingGuiFactory factory,
@NotNull Material itemMat, @NotNull Material itemMat,
@NotNull StringBuilder itemName, @NotNull StringBuilder itemName,
@NotNull Object value, @NotNull Object value,

View file

@ -26,13 +26,12 @@ import org.bukkit.inventory.InventoryView.Property.REPAIR_COST
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable import org.bukkit.inventory.meta.Repairable
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.packet.PacketManager
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import kotlin.math.min import kotlin.math.min
/** /**
* Listener for anvil events * Listener for anvil events
*/ */
@ -461,7 +460,7 @@ class AnvilEventListener(private val packetManager: PacketManager) : Listener {
val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, rightIsFormBook) val enchantmentMultiplier = ConfigOptions.enchantmentValue(enchantment.key, rightIsFormBook)
val value = resultLevel * enchantmentMultiplier val value = resultLevel * enchantmentMultiplier
CustomAnvil.log("Value for ${enchantment.key.enchantmentName} level ${enchantment.value} is $value") CustomAnvil.log("Value for ${enchantment.key.enchantmentName} level ${enchantment.value} is $value ($resultLevel * $enchantmentMultiplier)")
rightValue += value rightValue += value
} }

View file

@ -7,13 +7,11 @@ import org.bukkit.plugin.java.JavaPlugin
import xyz.alexcrea.cuanvil.command.EditConfigExecutor import xyz.alexcrea.cuanvil.command.EditConfigExecutor
import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.command.ReloadExecutor
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui import xyz.alexcrea.cuanvil.gui.config.MainConfigGui
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
import xyz.alexcrea.cuanvil.listener.ChatEventListener import xyz.alexcrea.cuanvil.listener.ChatEventListener
import xyz.alexcrea.cuanvil.packet.NoProtocoLib
import xyz.alexcrea.cuanvil.packet.PacketManager
import xyz.alexcrea.cuanvil.packet.ProtocoLibWrapper
import xyz.alexcrea.cuanvil.update.Update_1_21 import xyz.alexcrea.cuanvil.update.Update_1_21
import xyz.alexcrea.cuanvil.util.Metrics import xyz.alexcrea.cuanvil.util.Metrics
import java.io.File import java.io.File
@ -76,8 +74,6 @@ class CustomAnvil : JavaPlugin() {
} }
lateinit var packetManager: PacketManager
/** /**
* Setup plugin for use * Setup plugin for use
*/ */
@ -94,15 +90,12 @@ class CustomAnvil : JavaPlugin() {
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus") logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
} }
// Load dependency
DependencyManager.loadDependency()
// Register enchantments // Register enchantments
WrappedEnchantment.registerEnchantments() WrappedEnchantment.registerEnchantments()
// Load ProtocolLib dependency if exist
packetManager = if(pluginManager.isPluginEnabled("ProtocolLib"))
{ ProtocoLibWrapper(); }
else
{ NoProtocoLib(); }
// Load chat listener // Load chat listener
chatListener = ChatEventListener() chatListener = ChatEventListener()
pluginManager.registerEvents(chatListener, this) pluginManager.registerEvents(chatListener, this)
@ -114,8 +107,11 @@ class CustomAnvil : JavaPlugin() {
// temporary: handle 1.21 update // temporary: handle 1.21 update
Update_1_21.handleUpdate() Update_1_21.handleUpdate()
// Handle custom enchant config
DependencyManager.handleConfigChanges()
// Load gui constants //TODO maybe something better later // Load gui constants //TODO maybe something better later
MainConfigGui.getInstance().init(this.packetManager) MainConfigGui.getInstance().init(DependencyManager.packetManager)
GuiSharedConstant.loadConstants() GuiSharedConstant.loadConstants()
// Load metrics // Load metrics
@ -125,7 +121,7 @@ class CustomAnvil : JavaPlugin() {
prepareCommand() prepareCommand()
server.pluginManager.registerEvents( server.pluginManager.registerEvents(
AnvilEventListener(packetManager), AnvilEventListener(DependencyManager.packetManager),
this this
) )
} }

View file

@ -306,6 +306,15 @@ object ConfigOptions {
if(enchantmentName == "sweeping_edge"){ if(enchantmentName == "sweeping_edge"){
return enchantmentValue("sweeping", isFromBook) return enchantmentValue("sweeping", isFromBook)
} }
val enchantment = WrappedEnchantment.getByName(enchantmentName)
if(enchantment != null){
val rarity = enchantment.defaultRarity()
return if(isFromBook) rarity.bookValue
else rarity.itemValue
}
return DEFAULT_ENCHANT_VALUE return DEFAULT_ENCHANT_VALUE
} }

View file

@ -30,6 +30,8 @@ object EnchantmentUtil {
) = mutableMapOf<WrappedEnchantment, Int>().apply { ) = mutableMapOf<WrappedEnchantment, Int>().apply {
putAll(this@combineWith) putAll(this@combineWith)
other.forEach { (enchantment, level) -> other.forEach { (enchantment, level) ->
if(!enchantment.isAllowed(player)) return@forEach
// Get max level or 255 if player can bypass // Get max level or 255 if player can bypass
val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission)) val maxLevel = if (player.hasPermission(CustomAnvil.bypassLevelPermission))
{ 255 } else { 255 } else
@ -53,7 +55,7 @@ object EnchantmentUtil {
} }
// Enchantment already in result list // Enchantment already in result list
else { else {
val oldLevel = this[enchantment]!! // should be true, see the comment above val oldLevel = this[enchantment]!! // <- should not be null. see the comment above
// ... and they are conflicting // ... and they are conflicting
val conflictType = val conflictType =

View file

@ -0,0 +1,35 @@
package xyz.alexcrea.cuanvil.dependency
import org.bukkit.Bukkit
import xyz.alexcrea.cuanvil.dependency.protocolib.NoProtocoLib
import xyz.alexcrea.cuanvil.dependency.protocolib.PacketManager
import xyz.alexcrea.cuanvil.dependency.protocolib.ProtocoLibWrapper
object DependencyManager {
lateinit var packetManager: PacketManager
var enchantmentSquaredCompatibility: EnchantmentSquaredDependency? = null
fun loadDependency(){
val pluginManager = Bukkit.getPluginManager()
// ProtocolLib dependency
packetManager =
if(pluginManager.isPluginEnabled("ProtocolLib")) ProtocoLibWrapper()
else NoProtocoLib()
// Enchantment Squared dependency
if(pluginManager.isPluginEnabled("EnchantsSquared")){
enchantmentSquaredCompatibility = EnchantmentSquaredDependency(pluginManager.getPlugin("EnchantsSquared")!!)
enchantmentSquaredCompatibility!!.disableAnvilListener()
}
}
fun handleConfigChanges() {
enchantmentSquaredCompatibility?.registerPluginConfiguration()
}
}

View file

@ -0,0 +1,220 @@
package xyz.alexcrea.cuanvil.dependency
import io.delilaheve.CustomAnvil
import me.athlaeos.enchantssquared.enchantments.CustomEnchant
import me.athlaeos.enchantssquared.managers.CustomEnchantManager
import org.bukkit.NamespacedKey
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.Plugin
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.enchant.WrappedEnchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.EnchantSquaredEnchantment
import java.util.*
import kotlin.collections.ArrayList
class EnchantmentSquaredDependency(private val enchantmentSquaredPlugin: Plugin) {
fun disableAnvilListener(){
PrepareAnvilEvent.getHandlerList().unregister(this.enchantmentSquaredPlugin)
CustomAnvil.instance.logger.info("Enchantment Squared Detected !")
CustomAnvil.instance.logger.info("Please be aware that Custom Anvil is bypassing Enchantment Squared ")
CustomAnvil.instance.logger.info(
"compatible_with, " +
"disable_anvil, " +
"incompatible_vanilla_enchantments, " +
"incompatible_custom_enchantments and max_level " +
"configuration values.")
}
fun registerEnchantments(){
for (enchant in CustomEnchantManager.getInstance().allEnchants.values) {
WrappedEnchantment.register(EnchantSquaredEnchantment(enchant))
}
}
fun getEnchantmentsSquared(item: ItemStack, enchantments: MutableMap<WrappedEnchantment, Int>) {
val customEnchants = CustomEnchantManager.getInstance().getItemsEnchantsFromPDC(item)
customEnchants.forEach{
(enchantment, level ) -> enchantments[getWrappedEnchant(enchantment)] = level
}
}
fun clearEnchantments(item: ItemStack) {
CustomEnchantManager.getInstance().removeAllEnchants(item)
}
fun getKeyFromEnchant(enchant: CustomEnchant): NamespacedKey{
return NamespacedKey.fromString(enchant.type.lowercase(Locale.getDefault()), this.enchantmentSquaredPlugin)!!
}
private fun getWrappedEnchant(enchant: CustomEnchant): WrappedEnchantment{
return WrappedEnchantment.getByKey(getKeyFromEnchant(enchant))!!
}
private val IS_READY_PATH = "enchantment_square_ready"
fun registerPluginConfiguration(){
val defaultConfig = ConfigHolder.DEFAULT_CONFIG.config
val isReady = defaultConfig.getBoolean(IS_READY_PATH, false)
if(isReady) return
CustomAnvil.instance.logger.info("Preparing configuration for Enchantment Squared...")
// Prepare enchantments
val esEnchantments = ArrayList<EnchantSquaredEnchantment>()
CustomEnchantManager.getInstance().allEnchants.forEach { (_, enchant) ->
esEnchantments.add(getWrappedEnchant(enchant) as EnchantSquaredEnchantment)
}
// Write default level limit and xp cost
for (enchantment in esEnchantments) {
defaultConfig["enchant_limits.${enchantment.key.key}"] = enchantment.defaultMaxLevel()
val rarity = enchantment.defaultRarity()
defaultConfig["enchant_values.${enchantment.key.key}.item"] = rarity.itemValue
defaultConfig["enchant_values.${enchantment.key.key}.book"] = rarity.bookValue
}
// Write groups and conflicts
writeMissingGroups()
writeMaterialRestriction(esEnchantments)
writeEnchantmentConflicts(esEnchantments)
// Set ready
defaultConfig[IS_READY_PATH] = true
// Save
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true)
ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true)
ConfigHolder.CONFLICT_HOLDER.saveToDisk(true)
// Reload
ConfigHolder.ITEM_GROUP_HOLDER.reload()
CustomAnvil.instance.logger.info("Enchantment Squared should now work as expected !")
}
private fun writeMissingGroups(){
// Write group that do not exist on custom anvil.
// (Tools group regroup most of the tool items. I did not create a seperated group for theses)
val groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.config
if(!groupConfig.isConfigurationSection("pickaxes")){
groupConfig["pickaxes.type"] = "include"
groupConfig["pickaxes.items"] = listOf("wooden_pickaxe", "stone_pickaxe", "iron_pickaxe", "diamond_pickaxe", "golden_pickaxe", "netherite_pickaxe")
}
if(!groupConfig.isConfigurationSection("shovels")){
groupConfig["shovels.type"] = "include"
groupConfig["shovels.items"] = listOf("wooden_shovel", "stone_shovel", "iron_shovel", "diamond_shovel", "golden_shovel", "netherite_shovel")
}
if(!groupConfig.isConfigurationSection("hoes")){
groupConfig["hoes.type"] = "include"
groupConfig["hoes.items"] = listOf("wooden_hoe", "stone_ho", "iron_hoe", "diamond_hoe", "golden_hoe", "netherite_hoe")
}
if(!groupConfig.isConfigurationSection("shield")){
groupConfig["shield.type"] = "include"
groupConfig["shield.items"] = listOf("shield")
}
if(!groupConfig.isConfigurationSection("elytra")){
groupConfig["elytra.type"] = "include"
groupConfig["elytra.items"] = listOf("elytra")
}
if(!groupConfig.isConfigurationSection("trinkets")){
groupConfig["trinkets.type"] = "include"
groupConfig["trinkets.items"] = listOf("rotten_flesh")
}
}
private fun writeMaterialRestriction(esEnchantments: List<EnchantSquaredEnchantment>){
val conflictConfig = ConfigHolder.CONFLICT_HOLDER.config
for (enchantment in esEnchantments) {
val restrictionName = "restriction_${enchantment.key.key}"
if(!conflictConfig.isConfigurationSection(restrictionName)){
conflictConfig["$restrictionName.enchantments"] = listOf(enchantment.name)
// Get allowed groups
val listOfAllowed = ArrayList<String>()
listOfAllowed.add("enchanted_book") // enchanted book is allowed in any case.
for (esGroup in enchantment.enchant.compatibleItems) {
val caGroup = esGroupToCAGroup(esGroup)
if(caGroup == null){
CustomAnvil.instance.logger.info("Could not find equivalent custom anvil group for $esGroup")
continue
}
listOfAllowed.add(caGroup)
}
conflictConfig["$restrictionName.notAffectedGroups"] = listOfAllowed
}
}
}
private fun writeEnchantmentConflicts(esEnchantments: List<EnchantSquaredEnchantment>){
val otherEnchants = ArrayList<WrappedEnchantment>()
otherEnchants.addAll(WrappedEnchantment.values())
for (enchantment in esEnchantments) {
otherEnchants.remove(enchantment)
// find conflicting enchantment.
for (otherEnchant in otherEnchants) {
if(enchantment.enchant.conflictsWithEnchantment(otherEnchant.name)){
writeConflict(enchantment, otherEnchant)
}
}
}
}
private fun writeConflict(enchantment1: WrappedEnchantment, enchantment2: WrappedEnchantment){
val conflictConfig = ConfigHolder.CONFLICT_HOLDER.config
val conflictPath = "${enchantment1.name}_with_${enchantment2.name}_conflict"
if(!conflictConfig.isConfigurationSection(conflictPath)){
conflictConfig["$conflictPath.enchantments"] = listOf(enchantment1.name, enchantment2.name)
val empty: List<String> = Collections.emptyList()
conflictConfig["$conflictPath.notAffectedGroups"] = empty
conflictConfig["$conflictPath.maxEnchantmentBeforeConflict"] = 1
}
}
/**
* Transform an Enchantment Squared group to a Custom Anvil group
*/
private fun esGroupToCAGroup(esGroup: String): String? {
return when(esGroup){
"SWORDS" -> "swords"
"BOWS" -> "bow"
"CROSSBOWS" -> "crossbow"
"TRIDENTS" -> "trident"
"HELMETS" -> "helmets"
"CHESTPLATES" -> "chestplate"
"LEGGINGS" -> "leggings"
"BOOTS" -> "boots"
"SHEARS" -> "shears"
"FLINTANDSTEEL" -> "flint_and_steel"
"FISHINGROD" -> "fishing_rod"
"ELYTRA" -> "elytra"
"PICKAXES" -> "pickaxes" // not on this plugin by default
"AXES" -> "axes"
"SHOVELS" -> "shovels" // not on this plugin by default
"HOES" -> "hoes" // not on this plugin by default
"SHIELDS" -> "shield" // not on this plugin by default
"TRINKETS" -> "trinkets" // not the idea way as it will also allow non trinkets rotten flesh to be enchanted.
"ALL" -> "everything"
else -> null
}
}
}

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.packet package xyz.alexcrea.cuanvil.dependency.protocolib
import org.bukkit.entity.Player import org.bukkit.entity.Player

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.packet package xyz.alexcrea.cuanvil.dependency.protocolib
import org.bukkit.entity.Player import org.bukkit.entity.Player

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.packet package xyz.alexcrea.cuanvil.dependency.protocolib
import com.comphenix.protocol.PacketType import com.comphenix.protocol.PacketType
import com.comphenix.protocol.ProtocolLibrary import com.comphenix.protocol.ProtocolLibrary

View file

@ -93,7 +93,7 @@ class EnchantConflictManager {
conflict.addEnchantment(enchant) conflict.addEnchantment(enchant)
} }
if (conflict.getEnchants().size == 0) { if (conflict.getEnchants().size == 0) {
if (!futureUse) { if (!futureUse) { //TODO future use will be deprecated once the new update system is finished
CustomAnvil.instance.logger.warning("Conflict $conflictName do not have valid enchantment, it will not do anything") CustomAnvil.instance.logger.warning("Conflict $conflictName do not have valid enchantment, it will not do anything")
} }
} }

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# All anvil cost will be capped to limit_repair_value if enabled. # All anvil cost will be capped to limit_repair_value if enabled.
# #
# In other words: # In other words:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# material conflicts # material conflicts
# #
# If you want to edit this file: # If you want to edit this file:

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Please note this config use spigot material names. # Please note this config use spigot material names.
# It should match minecraft name in most case, maybe every case, but I can't be sure # It should match minecraft name in most case, maybe every case, but I can't be sure
# In case there an issue with material name, you can found them here: # In case there an issue with material name, you can found them here:

View file

@ -1,7 +1,7 @@
main: io.delilaheve.CustomAnvil main: io.delilaheve.CustomAnvil
name: CustomAnvil name: CustomAnvil
prefix: "Custom Anvil" prefix: "Custom Anvil"
version: 1.4.8 version: 1.5.0-beta
description: Allow to customise anvil mechanics description: Allow to customise anvil mechanics
api-version: 1.16 api-version: 1.16
load: POSTWORLD load: POSTWORLD
@ -46,3 +46,4 @@ permissions:
softdepend: softdepend:
- UnsafeEnchantsPlus - UnsafeEnchantsPlus
- ProtocolLib - ProtocolLib
- EnchantsSquared

View file

@ -1,3 +1,8 @@
#
# It is recommended that you use /configanvil to edit theses config.
# You can still manually edit here if you like to. but if you do, don't forget to /anvilconfigreload after you changes !
#
# Unit repair configuration # Unit repair configuration
# #
# This configuration is to make custom unit repair # This configuration is to make custom unit repair