alpha version up & cleanup code.

This commit is contained in:
alexcrea 2024-03-31 00:59:50 +01:00
parent 1b83c8db81
commit 00fba2f4b0
40 changed files with 893 additions and 718 deletions

View file

@ -4,7 +4,7 @@ plugins {
} }
group = "xyz.alexcrea" group = "xyz.alexcrea"
version = "1.3.2-A1" version = "1.3.2-A2"
repositories { repositories {
mavenCentral() mavenCentral()

View file

@ -49,12 +49,15 @@ public abstract class ConfigHolder {
private static final File BACKUP_FOLDER = new File(CustomAnvil.instance.getDataFolder(), "backup"); private static final File BACKUP_FOLDER = new File(CustomAnvil.instance.getDataFolder(), "backup");
protected FileConfiguration configuration; protected FileConfiguration configuration;
protected ConfigHolder() { protected ConfigHolder() {
} }
public abstract boolean reloadFromDisk(boolean hardFail); public abstract boolean reloadFromDisk(boolean hardFail);
public abstract void reload(); public abstract void reload();
public FileConfiguration getConfig() { public FileConfiguration getConfig() {
return configuration; return configuration;
} }
@ -65,12 +68,15 @@ public abstract class ConfigHolder {
protected String getConfigFileExtension() { protected String getConfigFileExtension() {
return ".yml"; return ".yml";
} }
protected File getConfigFile() { protected File getConfigFile() {
return new File(CustomAnvil.instance.getDataFolder(), getConfigFileName() + getConfigFileExtension()); return new File(CustomAnvil.instance.getDataFolder(), getConfigFileName() + getConfigFileExtension());
} }
protected File getFirstBackup() { protected File getFirstBackup() {
return new File(BACKUP_FOLDER, getConfigFileName() + "-first" + getConfigFileExtension()); return new File(BACKUP_FOLDER, getConfigFileName() + "-first" + getConfigFileExtension());
} }
protected File getLastBackup() { protected File getLastBackup() {
return new File(BACKUP_FOLDER, getConfigFileName() + "-latest" + getConfigFileExtension()); return new File(BACKUP_FOLDER, getConfigFileName() + "-latest" + getConfigFileExtension());
} }
@ -150,7 +156,8 @@ public abstract class ConfigHolder {
} }
@Override @Override
public void reload() {}// Nothing to do public void reload() {
}// Nothing to do
} }
@ -158,6 +165,7 @@ public abstract class ConfigHolder {
public abstract static class ResourceConfigHolder extends ConfigHolder { public abstract static class ResourceConfigHolder extends ConfigHolder {
String resourceName; String resourceName;
private ResourceConfigHolder(String resourceName) { private ResourceConfigHolder(String resourceName) {
this.resourceName = resourceName; this.resourceName = resourceName;
} }
@ -184,6 +192,7 @@ public abstract class ConfigHolder {
private final static String FILE_NAME = "item_groups"; private final static String FILE_NAME = "item_groups";
ItemGroupManager itemGroupsManager; ItemGroupManager itemGroupsManager;
private ItemGroupConfigHolder() { private ItemGroupConfigHolder() {
super(FILE_NAME); super(FILE_NAME);
} }
@ -210,6 +219,7 @@ public abstract class ConfigHolder {
private final static String FILE_NAME = "enchant_conflict"; private final static String FILE_NAME = "enchant_conflict";
EnchantConflictManager conflictManager; EnchantConflictManager conflictManager;
private ConflictConfigHolder() { private ConflictConfigHolder() {
super(FILE_NAME); super(FILE_NAME);
} }
@ -235,8 +245,10 @@ public abstract class ConfigHolder {
private UnitRepairHolder() { private UnitRepairHolder() {
super(ITEM_GROUP_FILE_NAME); super(ITEM_GROUP_FILE_NAME);
} }
@Override @Override
public void reload() {} // Do nothing public void reload() {
} // Do nothing
} }

View file

@ -41,11 +41,10 @@ public enum EnchantmentProperties {
SWEEPING(EnchantmentRarity.RARE), SWEEPING(EnchantmentRarity.RARE),
THORNS(EnchantmentRarity.VERY_RARE), THORNS(EnchantmentRarity.VERY_RARE),
UNBREAKING(EnchantmentRarity.UNCOMMON), UNBREAKING(EnchantmentRarity.UNCOMMON),
VANISHING_CURSE(EnchantmentRarity.VERY_RARE) VANISHING_CURSE(EnchantmentRarity.VERY_RARE);
;
private final EnchantmentRarity rarity; private final EnchantmentRarity rarity;
EnchantmentProperties(EnchantmentRarity rarity) { EnchantmentProperties(EnchantmentRarity rarity) {
this.rarity = rarity; this.rarity = rarity;
} }

View file

@ -7,9 +7,7 @@ public enum EnchantmentRarity {
COMMON(1), COMMON(1),
UNCOMMON(2), UNCOMMON(2),
RARE(4), RARE(4),
VERY_RARE(8) VERY_RARE(8);
;
private final int itemValue; private final int itemValue;
private final int bookValue; private final int bookValue;
@ -18,6 +16,7 @@ public enum EnchantmentRarity {
this.itemValue = itemValue; this.itemValue = itemValue;
this.bookValue = bookValue; this.bookValue = bookValue;
} }
EnchantmentRarity(int itemValue) { EnchantmentRarity(int itemValue) {
this(itemValue, Math.max(1, itemValue / 2)); this(itemValue, Math.max(1, itemValue / 2));
} }

View file

@ -14,12 +14,14 @@ import java.util.List;
/** /**
* 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 AbstractSettingGui.SettingGuiFactory> extends 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.
*
* @param title Title of the gui. * @param title Title of the gui.
*/ */
protected AbstractEnchantConfigGui(String title) { protected AbstractEnchantConfigGui(String title) {

View file

@ -24,6 +24,7 @@ public class ConfirmActionGui extends ChestGui {
private static final ItemStack CANCEL_ITEM; private static final ItemStack CANCEL_ITEM;
private static final ItemStack CONFIRM_ITEM; private static final ItemStack CONFIRM_ITEM;
static { static {
CANCEL_ITEM = new ItemStack(Material.RED_TERRACOTTA); CANCEL_ITEM = new ItemStack(Material.RED_TERRACOTTA);
ItemMeta meta = CANCEL_ITEM.getItemMeta(); ItemMeta meta = CANCEL_ITEM.getItemMeta();

View file

@ -31,6 +31,7 @@ import java.util.function.Consumer;
public class EnchantConflictGui extends ChestGui { public class EnchantConflictGui extends ChestGui {
public final static EnchantConflictGui INSTANCE = new EnchantConflictGui(); public final static EnchantConflictGui INSTANCE = new EnchantConflictGui();
static { static {
INSTANCE.init(); INSTANCE.init();
} }
@ -80,6 +81,7 @@ public class EnchantConflictGui extends ChestGui {
private GuiItem goLeftItem; private GuiItem goLeftItem;
private GuiItem goRightItem; private GuiItem goRightItem;
private void prepareOtherValues() { private void prepareOtherValues() {
// Left item creation for consumer & bind // Left item creation for consumer & bind
this.goLeftItem = new GuiItem(new ItemStack(Material.RED_TERRACOTTA), event -> { this.goLeftItem = new GuiItem(new ItemStack(Material.RED_TERRACOTTA), event -> {

View file

@ -46,7 +46,8 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
EnchantmentRarity rarity = EnchantmentRarity.NO_RARITY; EnchantmentRarity rarity = EnchantmentRarity.NO_RARITY;
try { try {
rarity = EnchantmentProperties.valueOf(key.toUpperCase(Locale.ENGLISH)).getRarity(); rarity = EnchantmentProperties.valueOf(key.toUpperCase(Locale.ENGLISH)).getRarity();
}catch (IllegalArgumentException ignored){} } catch (IllegalArgumentException ignored) {
}
return EnchantCostSettingsGui.enchantCostFactory(prettyKey + " Level Cost", this, return EnchantCostSettingsGui.enchantCostFactory(prettyKey + " Level Cost", this,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, 0, 255, SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG, 0, 255,

View file

@ -20,6 +20,7 @@ public class MainConfigGui extends ChestGui {
static { static {
INSTANCE.init(); INSTANCE.init();
} }
private MainConfigGui() { private MainConfigGui() {
super(3, "\u00A78Anvil Config", CustomAnvil.instance); super(3, "\u00A78Anvil Config", CustomAnvil.instance);

View file

@ -26,6 +26,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Prepare necessary object for a setting gui. * Prepare necessary object for a setting gui.
*
* @param rows Number of row for this gui. * @param rows Number of row for this gui.
* @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.
@ -37,6 +38,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Prepare necessary object for a setting gui. * Prepare necessary object for a setting gui.
*
* @param rows Number of row for this gui. * @param rows Number of row for this gui.
* @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.
@ -50,6 +52,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Initialise and prepare value for this gui. * Initialise and prepare value for this gui.
*
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
*/ */
private void initBase(ValueUpdatableGui parent) { private void initBase(ValueUpdatableGui parent) {
@ -75,6 +78,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Get main pane for this setting gui. * Get main pane for this setting gui.
*
* @return Main pattern pain of this gui. * @return Main pattern pain of this gui.
*/ */
protected PatternPane getPane() { protected PatternPane getPane() {
@ -89,12 +93,14 @@ public abstract class AbstractSettingGui extends ChestGui {
* <li><b>B</b>: "back to previous gui" button.</li> * <li><b>B</b>: "back to previous gui" button.</li>
* <li><b>0</b>: default background item.</li> * <li><b>0</b>: default background item.</li>
* </ul> * </ul>
*
* @return The gui's pattern. * @return The gui's pattern.
*/ */
protected abstract Pattern getGuiPattern(); protected abstract Pattern getGuiPattern();
/** /**
* Called when the associated setting need to be saved. * Called when the associated setting need to be saved.
*
* @return true if the save was successful. false otherwise * @return true if the save was successful. false otherwise
*/ */
public abstract boolean onSave(); public abstract boolean onSave();
@ -102,6 +108,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* If this function return true * If this function return true
* the gui assume the associated setting can be saved. * the gui assume the associated setting can be saved.
*
* @return true if there is a change to the setting. false otherwise * @return true if there is a change to the setting. false otherwise
*/ */
public abstract boolean hadChange(); public abstract boolean hadChange();
@ -117,6 +124,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Constructor for settings gui factory * Constructor for settings gui factory
*
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting. * @param config Configuration holder of this setting.
*/ */
@ -141,6 +149,7 @@ public abstract class AbstractSettingGui extends ChestGui {
/** /**
* Create a gui using setting parameters and current setting value. * Create a gui using setting parameters and current setting value.
*
* @return A new instance of the implemented setting gui. * @return A new instance of the implemented setting gui.
*/ */
public abstract AbstractSettingGui create(); public abstract AbstractSettingGui create();

View file

@ -29,6 +29,7 @@ public class BoolSettingsGui extends AbstractSettingGui{
/** /**
* Create a boolean setting config gui. * Create a boolean setting config gui.
*
* @param holder Configuration factory of this setting. * @param holder Configuration factory of this setting.
* @param now The defined value of this setting. * @param now The defined value of this setting.
*/ */
@ -139,6 +140,7 @@ public class BoolSettingsGui extends AbstractSettingGui{
/** /**
* Create a bool setting factory from setting's parameters. * Create a bool setting factory from setting's parameters.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.
@ -159,11 +161,14 @@ public class BoolSettingsGui extends AbstractSettingGui{
* A factory for a boolean setting gui that hold setting's information. * A factory for a boolean setting gui that hold setting's information.
*/ */
public static class BoolSettingFactory extends SettingGuiFactory { public static class BoolSettingFactory extends SettingGuiFactory {
@NotNull String title; ValueUpdatableGui parent; @NotNull
String title;
ValueUpdatableGui parent;
boolean defaultVal; boolean defaultVal;
/** /**
* Constructor for a boolean setting gui factory. * Constructor for a boolean setting gui factory.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.

View file

@ -34,6 +34,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
/** /**
* Create an enchantment cost setting config gui. * Create an enchantment cost setting config gui.
*
* @param holder Configuration factory of this setting. * @param holder Configuration factory of this setting.
* @param nowItem The defined value of this setting item's value. * @param nowItem The defined value of this setting item's value.
*/ */
@ -81,7 +82,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
bookMeta.setDisplayName("\u00A7aCost of an Enchantment by Book"); bookMeta.setDisplayName("\u00A7aCost of an Enchantment by Book");
bookMeta.setLore(Arrays.asList( bookMeta.setLore(Arrays.asList(
"\u00A77Cost per result item level of an sacrifice enchantment", "\u00A77Cost per result item level of an sacrifice enchantment",
"\u00A77Only apply if sacrificed item \u00A7cis \u00A77a book"));bookItemstack.setItemMeta(bookMeta); "\u00A77Only apply if sacrificed item \u00A7cis \u00A77a book"));
bookItemstack.setItemMeta(bookMeta);
// sword display // sword display
ItemStack swordItemstack = new ItemStack(Material.WOODEN_SWORD); ItemStack swordItemstack = new ItemStack(Material.WOODEN_SWORD);
@ -221,6 +223,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
/** /**
* Create an int setting factory from setting's parameters. * Create an int setting factory from setting's parameters.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.
@ -255,6 +258,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
/** /**
* Constructor for an enchantment cost setting gui factory. * Constructor for an enchantment cost setting gui factory.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.

View file

@ -20,7 +20,10 @@ import xyz.alexcrea.cuanvil.gui.config.SelectGroupContainer;
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.*; import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
public class GroupSelectSettingGui extends AbstractSettingGui { public class GroupSelectSettingGui extends AbstractSettingGui {

View file

@ -32,6 +32,7 @@ public class IntSettingsGui extends AbstractSettingGui{
/** /**
* Create an int setting config gui. * Create an int setting config gui.
*
* @param holder Configuration factory of this setting. * @param holder Configuration factory of this setting.
* @param now The defined value of this setting. * @param now The defined value of this setting.
*/ */
@ -59,6 +60,7 @@ public class IntSettingsGui extends AbstractSettingGui{
} }
protected GuiItem returnToDefault; protected GuiItem returnToDefault;
/** /**
* Prepare "return to default value" gui item. * Prepare "return to default value" gui item.
*/ */
@ -186,6 +188,7 @@ public class IntSettingsGui extends AbstractSettingGui{
/** /**
* Step use lower case character from 'a' to a certain char. * Step use lower case character from 'a' to a certain char.
*
* @return The middle value of the character set for steps. * @return The middle value of the character set for steps.
*/ */
protected char getMidStepChar() { protected char getMidStepChar() {
@ -194,6 +197,7 @@ public class IntSettingsGui extends AbstractSettingGui{
/** /**
* Create a step item from a step value. * Create a step item from a step value.
*
* @param stepIndex the index of the step item. * @param stepIndex the index of the step item.
* @return A step item corresponding to its index value. * @return A step item corresponding to its index value.
*/ */
@ -261,6 +265,7 @@ public class IntSettingsGui extends AbstractSettingGui{
/** /**
* Create an int setting factory from setting's parameters. * Create an int setting factory from setting's parameters.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.
@ -287,11 +292,17 @@ public class IntSettingsGui extends AbstractSettingGui{
* A factory for an int setting gui that hold setting's information. * A factory for an int setting gui that hold setting's information.
*/ */
public static class IntSettingFactory extends SettingGuiFactory { public static class IntSettingFactory extends SettingGuiFactory {
@NotNull String title; ValueUpdatableGui parent; @NotNull
int min; int max; int defaultVal; int[] steps; String title;
ValueUpdatableGui parent;
int min;
int max;
int defaultVal;
int[] steps;
/** /**
* Constructor for an int setting gui factory. * Constructor for an int setting gui factory.
*
* @param title The title of the gui. * @param title The title of the gui.
* @param parent Parent gui to go back when completed. * @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting. * @param configPath Configuration path of this setting.

View file

@ -27,6 +27,7 @@ public class GuiGlobalActions {
/** /**
* Create a consumer to create and open a new GUI. * Create a consumer to create and open a new GUI.
* Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem. * Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem.
*
* @param clazz The class of the gui to open. * @param clazz The class of the gui to open.
* It is assumed this class contain a constructor requiring arguments of argClass in the same order as argClass array. * It is assumed this class contain a constructor requiring arguments of argClass in the same order as argClass array.
* @param argClass Classes of the argument that will be passed to the constructor of the GUI class. * @param argClass Classes of the argument that will be passed to the constructor of the GUI class.
@ -62,6 +63,7 @@ public class GuiGlobalActions {
/** /**
* Create a consumer to create and open a new GUI. * Create a consumer to create and open a new GUI.
* Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem. * Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem.
*
* @param clazz The class of the gui to open. * @param clazz The class of the gui to open.
* It is assumed this class contain a constructor with no argument. * It is assumed this class contain a constructor with no argument.
* @return A consumer to create a new gui and open it. * @return A consumer to create a new gui and open it.
@ -74,6 +76,7 @@ public class GuiGlobalActions {
/** /**
* Create a consumer to open a setting gui from a setting GUI factory. * Create a consumer to open a setting gui from a setting GUI factory.
* Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem. * Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem.
*
* @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.
*/ */
@ -88,6 +91,7 @@ public class GuiGlobalActions {
/** /**
* Create a consumer to open a global GUI. * Create a consumer to open a global GUI.
* Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem. * Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem.
*
* @param goal The gui to open when consumer is run. * @param goal The gui to open when consumer is run.
* @return A consumer to open a global GUI. * @return A consumer to open a global GUI.
*/ */
@ -109,6 +113,7 @@ public class GuiGlobalActions {
* Create a consumer to update and open an updatable GUI. * Create a consumer to update and open an updatable GUI.
* Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem. * Used with InventoryClickEvent as the consumer argument as it is planned to be used on click on an GuiItem.
* This consumer check if the player who interacted with the item have the permission to save before saving. * This consumer check if the player who interacted with the item have the permission to save before saving.
*
* @param setting The gui that contain the modified setting. * @param setting The gui that contain the modified setting.
* @param goal The gui to update and open when consumer is run. * @param goal The gui to update and open when consumer is run.
* @return A consumer to open a global GUI. * @return A consumer to open a global GUI.

View file

@ -23,6 +23,7 @@ public class GuiGlobalItems {
// statically create default back itemstack // statically create default back itemstack
private static final ItemStack BACK_ITEM; private static final ItemStack BACK_ITEM;
static { static {
BACK_ITEM = new ItemStack(Material.BARRIER); BACK_ITEM = new ItemStack(Material.BARRIER);
ItemMeta meta = BACK_ITEM.getItemMeta(); ItemMeta meta = BACK_ITEM.getItemMeta();
@ -32,6 +33,7 @@ public class GuiGlobalItems {
/** /**
* Create a GuiItem that open the given GUi. * Create a GuiItem that open the given GUi.
*
* @param item The item to display in the GUI. * @param item The item to display in the GUI.
* @param goal The GUI to open on click. * @param goal The GUI to open on click.
* @return An GuiItem that open goal on click. * @return An GuiItem that open goal on click.
@ -43,6 +45,7 @@ public class GuiGlobalItems {
/** /**
* Create back button item from default back GuiItem. * Create back button item from default back GuiItem.
* The back item will open the goal inventory when clicked. * The back item will open the goal inventory when clicked.
*
* @param goal The GUI to go back to. * @param goal The GUI to go back to.
* @return An GuiItem that go back to goal on click. * @return An GuiItem that go back to goal on click.
*/ */
@ -53,6 +56,7 @@ public class GuiGlobalItems {
/** /**
* Add default back item to a GUI pattern with the reserved character key <strong>B</strong>. * Add default back item to a GUI pattern with the reserved character key <strong>B</strong>.
* The back item will open the target inventory when clicked. * The back item will open the target inventory when clicked.
*
* @param target The pattern to add the back item. * @param target The pattern to add the back item.
* @param goal The GUI to go back to. * @param goal The GUI to go back to.
*/ */
@ -66,6 +70,7 @@ public class GuiGlobalItems {
/** /**
* Get a background item with backgroundMat as the displayed material. * Get a background item with backgroundMat as the displayed material.
* A background item is a GuiItem that do nothing when interacted with and have an empty name. * A background item is a GuiItem that do nothing when interacted with and have an empty name.
*
* @param backgroundMat The material to which the background item should be made of. * @param backgroundMat The material to which the background item should be made of.
* @return A background item with backgroundMat as material. * @return A background item with backgroundMat as material.
*/ */
@ -76,9 +81,11 @@ public class GuiGlobalItems {
item.setItemMeta(meta); item.setItemMeta(meta);
return new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance); return new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
} }
/** /**
* Get default background GuiItem. * Get default background GuiItem.
* A background item is a GuiItem that do nothing when interacted with and have an empty name. * A background item is a GuiItem that do nothing when interacted with and have an empty name.
*
* @return A new instance of the default background item. * @return A new instance of the default background item.
*/ */
public static GuiItem backgroundItem() { public static GuiItem backgroundItem() {
@ -88,6 +95,7 @@ public class GuiGlobalItems {
/** /**
* Add default background item to a GUI pattern with the reserved character key <strong>0</strong>. * Add default background item to a GUI pattern with the reserved character key <strong>0</strong>.
* A background item is a GuiItem that do nothing when interacted with and have an empty name. * A background item is a GuiItem that do nothing when interacted with and have an empty name.
*
* @param target The pattern to add the background item. * @param target The pattern to add the background item.
* @param backgroundMat The material of the background item. * @param backgroundMat The material of the background item.
*/ */
@ -99,6 +107,7 @@ public class GuiGlobalItems {
/** /**
* Add default background item to a GUI pattern with the reserved character key <strong>0</strong>. * Add default background item to a GUI pattern with the reserved character key <strong>0</strong>.
* A background item is a GuiItem that do nothing when interacted with and have an empty name. * A background item is a GuiItem that do nothing when interacted with and have an empty name.
*
* @param target The pattern to add the background item. * @param target The pattern to add the background item.
*/ */
public static void addBackgroundItem(@NotNull PatternPane target) { public static void addBackgroundItem(@NotNull PatternPane target) {
@ -112,6 +121,7 @@ public class GuiGlobalItems {
* Create a new save setting GuiItem. * Create a new save setting GuiItem.
* A save setting item is a GuiItem that save a changed setting when clicked. * A save setting item is a GuiItem that save a changed setting when clicked.
* This item also check if the player who interacted with the item have the permission to save before saving. * This item also check if the player who interacted with the item have the permission to save before saving.
*
* @param setting The setting to change. * @param setting The setting to change.
* @param goal Parent GUI of this setting GUI. as setting will be change the display of goal GUI will be updated. * @param goal Parent GUI of this setting GUI. as setting will be change the display of goal GUI will be updated.
* @return A save setting item. * @return A save setting item.
@ -131,6 +141,7 @@ public class GuiGlobalItems {
// Create static non change item // Create static non change item
private static final GuiItem NO_CHANGE_ITEM; private static final GuiItem NO_CHANGE_ITEM;
static { static {
ItemStack item = new ItemStack(DEFAULT_NO_CHANGE_ITEM); ItemStack item = new ItemStack(DEFAULT_NO_CHANGE_ITEM);
ItemMeta meta = item.getItemMeta(); ItemMeta meta = item.getItemMeta();
@ -142,6 +153,7 @@ public class GuiGlobalItems {
/** /**
* Get the global "no change" GuiItem. * Get the global "no change" GuiItem.
* The no change item do nothing when interacted, only the title is change to show there is no change. * The no change item do nothing when interacted, only the title is change to show there is no change.
*
* @return The global "no change" item. * @return The global "no change" item.
*/ */
public static GuiItem noChangeItem() { public static GuiItem noChangeItem() {
@ -151,6 +163,7 @@ public class GuiGlobalItems {
/** /**
* Create a new "create and go to the setting GUI" GuiItem. * Create a new "create and go to the setting GUI" GuiItem.
* This item will create and open a setting GUI from the factory. * This item will create and open a setting GUI from the factory.
*
* @param item The item that will be displayed. * @param item The item that will be displayed.
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @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.
@ -169,6 +182,7 @@ public class GuiGlobalItems {
* Create a new Boolean setting GuiItem. * Create a new Boolean setting GuiItem.
* This item will create and open a boolean setting GUI from the factory. * 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. * The item will have its value written in the lore part of the item.
*
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @param name Name of the item. * @param name Name of the item.
* @return A formatted GuiItem that will create and open a GUI for the boolean setting. * @return A formatted GuiItem that will create and open a GUI for the boolean setting.
@ -199,6 +213,7 @@ public class GuiGlobalItems {
* This item will create and open a boolean setting GUI from the factory. * 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. * The item will have its value written in the lore part of the item.
* Item's name will be the factory set title. * Item's name will be the factory set title.
*
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @return A formatted GuiItem that will create and open a GUI for the boolean setting. * @return A formatted GuiItem that will create and open a GUI for the boolean setting.
*/ */
@ -213,6 +228,7 @@ public class GuiGlobalItems {
* Create a new int setting GuiItem. * Create a new int setting GuiItem.
* This item will create and open an int setting GUI from the factory. * 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. * The item will have its value written in the lore part of the item.
*
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @param itemMat Displayed material of the item. * @param itemMat Displayed material of the item.
* @param name Name of the item. * @param name Name of the item.
@ -235,6 +251,7 @@ public class GuiGlobalItems {
* This item will create and open an int setting GUI from the factory. * 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. * The item will have its value written in the lore part of the item.
* Item's name will be the factory set title. * Item's name will be the factory set title.
*
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @param itemMat Displayed material of the item. * @param itemMat Displayed material of the item.
* @return A formatted GuiItem that will create and open a GUI for the int setting. * @return A formatted GuiItem that will create and open a GUI for the int setting.
@ -249,6 +266,7 @@ public class GuiGlobalItems {
/** /**
* Create an arbitrary GuiItem from a unique setting and item's property. * Create an arbitrary GuiItem from a unique setting and item's property.
*
* @param factory The setting's GUI factory. * @param factory The setting's GUI factory.
* @param itemMat Displayed material of the item. * @param itemMat Displayed material of the item.
* @param itemName Name of the item. * @param itemName Name of the item.
@ -277,6 +295,7 @@ public class GuiGlobalItems {
/** /**
* Get the setting name from the setting path. * Get the setting name from the setting path.
* For example: "gui.command.name" will return "name". * For example: "gui.command.name" will return "name".
*
* @param path The setting's path. * @param path The setting's path.
* @return The setting's name. * @return The setting's name.
*/ */

View file

@ -31,6 +31,7 @@ public class GuiSharedConstant {
public static final boolean TEMPORARY_DO_BACKUP_EVERY_SAVE = true; public static final boolean TEMPORARY_DO_BACKUP_EVERY_SAVE = true;
public static final PatternPane BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE; public static final PatternPane BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE;
static { static {
Pattern pattern = new Pattern( Pattern pattern = new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE, GuiSharedConstant.EMPTY_GUI_FULL_LINE,

View file

@ -9,6 +9,7 @@ public class CasedStringUtil {
* Transform a snake cased string to an upper-cased spaced string. * Transform a snake cased string to an upper-cased spaced string.
* <p> * <p>
* for example: if we use "hello_world" as an input this function will return "Hello World". * for example: if we use "hello_world" as an input this function will return "Hello World".
*
* @param snake_cased_string The input string. * @param snake_cased_string The input string.
* This argument NEED to be a snake cased string, or it will not work * This argument NEED to be a snake cased string, or it will not work
* @return The input as an upper-cased string with space separator. * @return The input as an upper-cased string with space separator.

View file

@ -39,6 +39,7 @@ class AnvilEventListener : Listener {
private const val ANVIL_INPUT_LEFT = 0 private const val ANVIL_INPUT_LEFT = 0
private const val ANVIL_INPUT_RIGHT = 1 private const val ANVIL_INPUT_RIGHT = 1
private const val ANVIL_OUTPUT_SLOT = 2 private const val ANVIL_OUTPUT_SLOT = 2
// static slot container // static slot container
private val NO_SLOT = SlotContainer(SlotType.NO_SLOT, 0) private val NO_SLOT = SlotContainer(SlotType.NO_SLOT, 0)
private val CURSOR_SLOT = SlotContainer(SlotType.CURSOR, 0) private val CURSOR_SLOT = SlotContainer(SlotType.CURSOR, 0)
@ -160,7 +161,9 @@ class AnvilEventListener : Listener {
val player = event.whoClicked as? Player ?: return val player = event.whoClicked as? Player ?: return
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
val inventory = event.inventory as? AnvilInventory ?: return val inventory = event.inventory as? AnvilInventory ?: return
if (event.rawSlot != ANVIL_OUTPUT_SLOT) { return } if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
return
}
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT) val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
@ -173,7 +176,8 @@ class AnvilEventListener : Listener {
// True if there was no change or not allowed // True if there was no change or not allowed
if ((output == inventory.getItem(ANVIL_INPUT_LEFT)) if ((output == inventory.getItem(ANVIL_INPUT_LEFT))
|| !allowed){ || !allowed
) {
event.result = Event.Result.DENY event.result = Event.Result.DENY
return return
@ -185,23 +189,28 @@ class AnvilEventListener : Listener {
if (canMerge) { if (canMerge) {
event.result = Event.Result.ALLOW event.result = Event.Result.ALLOW
} else if (unitRepairResult != null) { } else if (unitRepairResult != null) {
onUnitRepairExtract(leftItem, rightItem, output, onUnitRepairExtract(
unitRepairResult, event, player, inventory) leftItem, rightItem, output,
unitRepairResult, event, player, inventory
)
return return
} }
} }
private fun onUnitRepairExtract(leftItem: ItemStack, private fun onUnitRepairExtract(
leftItem: ItemStack,
rightItem: ItemStack, rightItem: ItemStack,
output: ItemStack, output: ItemStack,
unitRepairResult: Double, unitRepairResult: Double,
event: InventoryClickEvent, event: InventoryClickEvent,
player: Player, player: Player,
inventory: AnvilInventory){ inventory: AnvilInventory
) {
val resultCopy = leftItem.clone() val resultCopy = leftItem.clone()
val resultAmount = resultCopy.unitRepair( val resultAmount = resultCopy.unitRepair(
rightItem.amount, unitRepairResult) rightItem.amount, unitRepairResult
)
// To avoid vanilla, we cancel the event for unit repair // To avoid vanilla, we cancel the event for unit repair
event.result = Event.Result.DENY event.result = Event.Result.DENY
@ -228,7 +237,8 @@ class AnvilEventListener : Listener {
repairCost += resultAmount * ConfigOptions.unitRepairCost repairCost += resultAmount * ConfigOptions.unitRepairCost
if ((inventory.maximumRepairCost < repairCost) if ((inventory.maximumRepairCost < repairCost)
|| (player.level < repairCost)) return || (player.level < repairCost)
) return
} }
// If not creative middle click... // If not creative middle click...
if (event.click != ClickType.MIDDLE) { if (event.click != ClickType.MIDDLE) {
@ -291,8 +301,11 @@ class AnvilEventListener : Listener {
// Calculate work penalty // Calculate work penalty
val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0 val leftPenalty = (left.itemMeta as? Repairable)?.repairCost ?: 0
val rightPenalty = val rightPenalty =
if(right == null){ 0 } if (right == null) {
else{ (right.itemMeta as? Repairable)?.repairCost ?: 0 } 0
} else {
(right.itemMeta as? Repairable)?.repairCost ?: 0
}
// Try to set work penalty for the result item // Try to set work penalty for the result item
result.itemMeta?.let { result.itemMeta?.let {
@ -300,10 +313,12 @@ class AnvilEventListener : Listener {
result.itemMeta = it result.itemMeta = it
} }
CustomAnvil.log("Calculated penalty: " + CustomAnvil.log(
"Calculated penalty: " +
"leftPenalty: $leftPenalty, " + "leftPenalty: $leftPenalty, " +
"rightPenalty: $rightPenalty, " + "rightPenalty: $rightPenalty, " +
"result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}") "result penalty: ${(result.itemMeta as? Repairable)?.repairCost ?: "none"}"
)
return leftPenalty + rightPenalty return leftPenalty + rightPenalty
} }
@ -325,7 +340,11 @@ class AnvilEventListener : Listener {
// count enchant as illegal enchant if it conflicts with another enchant or not in result // count enchant as illegal enchant if it conflicts with another enchant or not in result
if ((enchantment.key !in resultEnchsKeys)) { if ((enchantment.key !in resultEnchsKeys)) {
resultEnchsKeys.add(enchantment.key) resultEnchsKeys.add(enchantment.key)
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(resultEnchsKeys,result.type,enchantment.key) val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(
resultEnchsKeys,
result.type,
enchantment.key
)
resultEnchsKeys.remove(enchantment.key) resultEnchsKeys.remove(enchantment.key)
if (ConflictType.BIG_CONFLICT == conflictType) { if (ConflictType.BIG_CONFLICT == conflictType) {
@ -342,9 +361,11 @@ class AnvilEventListener : Listener {
rightValue += value rightValue += value
} }
CustomAnvil.log("Calculated right values: " + CustomAnvil.log(
"Calculated right values: " +
"rightValue: $rightValue, " + "rightValue: $rightValue, " +
"illegalPenalty: $illegalPenalty") "illegalPenalty: $illegalPenalty"
)
return rightValue + illegalPenalty return rightValue + illegalPenalty
} }
@ -352,15 +373,16 @@ class AnvilEventListener : Listener {
/** /**
* Display xp needed for the work on the anvil inventory * Display xp needed for the work on the anvil inventory
*/ */
private fun handleAnvilXp(inventory: AnvilInventory, private fun handleAnvilXp(
inventory: AnvilInventory,
event: PrepareAnvilEvent, event: PrepareAnvilEvent,
anvilCost: Int){ anvilCost: Int
) {
// Test repair cost limit // Test repair cost limit
val finalAnvilCost: Int val finalAnvilCost = if (ConfigOptions.limitRepairCost) {
if (ConfigOptions.limitRepairCost) { min(anvilCost, ConfigOptions.limitRepairValue)
finalAnvilCost = min(anvilCost, ConfigOptions.limitRepairValue)
} else { } else {
finalAnvilCost = anvilCost anvilCost
} }
/* Because Minecraft likes to have the final say in the repair cost displayed /* Because Minecraft likes to have the final say in the repair cost displayed

View file

@ -24,17 +24,22 @@ class CustomAnvil : JavaPlugin() {
// Permission string required to use the plugin's features // Permission string required to use the plugin's features
const val affectedByPluginPermission = "ca.affected" const val affectedByPluginPermission = "ca.affected"
// Permission string required to bypass enchantment conflicts test // Permission string required to bypass enchantment conflicts test
const val bypassFusePermission = "ca.bypass.fuse" const val bypassFusePermission = "ca.bypass.fuse"
// Permission string required to bypass enchantment conflicts test // Permission string required to bypass enchantment conflicts test
const val bypassLevelPermission = "ca.bypass.level" const val bypassLevelPermission = "ca.bypass.level"
// Permission string required to reload the config // Permission string required to reload the config
const val commandReloadPermission = "ca.command.reload" const val commandReloadPermission = "ca.command.reload"
// Permission string required to edit the plugin's config // Permission string required to edit the plugin's config
const val editConfigPermission = "ca.config.edit" const val editConfigPermission = "ca.config.edit"
// Command Name to reload the config // Command Name to reload the config
const val commandReloadName = "anvilconfigreload" const val commandReloadName = "anvilconfigreload"
// Test command name // Test command name
const val commandTestName = "customanvilconfig" const val commandTestName = "customanvilconfig"
@ -98,8 +103,10 @@ class CustomAnvil : JavaPlugin() {
) )
} }
fun reloadResource(resourceName: String, fun reloadResource(
hardFailSafe:Boolean = true): YamlConfiguration?{ resourceName: String,
hardFailSafe: Boolean = true
): YamlConfiguration? {
// Save default resource // Save default resource
val file = File(dataFolder, resourceName) val file = File(dataFolder, resourceName)
if (!file.exists()) { if (!file.exists()) {

View file

@ -12,67 +12,94 @@ object ConfigOptions {
// Path for default enchantment limits // Path for default enchantment limits
private const val DEFAULT_LIMIT_PATH = "default_limit" private const val DEFAULT_LIMIT_PATH = "default_limit"
// Path for limiting repair cost // Path for limiting repair cost
const val LIMIT_REPAIR_COST = "limit_repair_cost" const val LIMIT_REPAIR_COST = "limit_repair_cost"
// Path for repair value limit // Path for repair value limit
const val LIMIT_REPAIR_VALUE = "limit_repair_value" const val LIMIT_REPAIR_VALUE = "limit_repair_value"
// Path for level cost on item repair // Path for level cost on item repair
const val ITEM_REPAIR_COST = "item_repair_cost" const val ITEM_REPAIR_COST = "item_repair_cost"
// Path for level cost on unit repair // Path for level cost on unit repair
const val UNIT_REPAIR_COST = "unit_repair_cost" const val UNIT_REPAIR_COST = "unit_repair_cost"
// Path for level cost on item renaming // Path for level cost on item renaming
const val ITEM_RENAME_COST = "item_rename_cost" const val ITEM_RENAME_COST = "item_rename_cost"
// Path for level cost on illegal enchantment on sacrifice // Path for level cost on illegal enchantment on sacrifice
const val SACRIFICE_ILLEGAL_COST = "sacrifice_illegal_enchant_cost" const val SACRIFICE_ILLEGAL_COST = "sacrifice_illegal_enchant_cost"
// Path for removing repair cost limits // Path for removing repair cost limits
const val REMOVE_REPAIR_LIMIT = "remove_repair_limit" const val REMOVE_REPAIR_LIMIT = "remove_repair_limit"
// Root path for enchantment limits // Root path for enchantment limits
const val ENCHANT_LIMIT_ROOT = "enchant_limits" const val ENCHANT_LIMIT_ROOT = "enchant_limits"
// Root path for enchantment values // Root path for enchantment values
const val ENCHANT_VALUES_ROOT = "enchant_values" const val ENCHANT_VALUES_ROOT = "enchant_values"
// Keys for specific enchantment values // Keys for specific enchantment values
private const val KEY_BOOK = "book" private const val KEY_BOOK = "book"
private const val KEY_ITEM = "item" private const val KEY_ITEM = "item"
// Debug logging toggle path // Debug logging toggle path
private const val DEBUG_LOGGING = "debug_log" private const val DEBUG_LOGGING = "debug_log"
// Debug verbose logging toggle path // Debug verbose logging toggle path
private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose" private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose"
// Default value for enchantment limits // Default value for enchantment limits
private const val DEFAULT_ENCHANT_LIMIT = 5 private const val DEFAULT_ENCHANT_LIMIT = 5
// Default value for limiting repair cost // Default value for limiting repair cost
const val DEFAULT_LIMIT_REPAIR = false const val DEFAULT_LIMIT_REPAIR = false
// Default value for repair cost limit // Default value for repair cost limit
const val DEFAULT_LIMIT_REPAIR_VALUE = 39 const val DEFAULT_LIMIT_REPAIR_VALUE = 39
// Default value for level cost on item repair // Default value for level cost on item repair
const val DEFAULT_ITEM_REPAIR_COST = 2 const val DEFAULT_ITEM_REPAIR_COST = 2
// Default value for level cost per unit repair // Default value for level cost per unit repair
const val DEFAULT_UNIT_REPAIR_COST = 1 const val DEFAULT_UNIT_REPAIR_COST = 1
// Default value for level cost on item renaming // Default value for level cost on item renaming
const val DEFAULT_ITEM_RENAME_COST = 1 const val DEFAULT_ITEM_RENAME_COST = 1
// Default value for level cost on illegal enchantment on sacrifice // Default value for level cost on illegal enchantment on sacrifice
const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1 const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1
// Valid range for repair cost limit // Valid range for repair cost limit
@JvmField @JvmField
val REPAIR_LIMIT_RANGE = 1..39 val REPAIR_LIMIT_RANGE = 1..39
// Valid range for repair cost // Valid range for repair cost
@JvmField @JvmField
val REPAIR_COST_RANGE = 0..255 val REPAIR_COST_RANGE = 0..255
// Valid range for rename cost // Valid range for rename cost
@JvmField @JvmField
val ITEM_RENAME_COST_RANGE = 0..255 val ITEM_RENAME_COST_RANGE = 0..255
// Valid range for illegal enchantment conflict cost // Valid range for illegal enchantment conflict cost
@JvmField @JvmField
val SACRIFICE_ILLEGAL_COST_RANGE = 0..255 val SACRIFICE_ILLEGAL_COST_RANGE = 0..255
// Default for removing repair cost limits // Default for removing repair cost limits
const val DEFAULT_REMOVE_LIMIT = false const val DEFAULT_REMOVE_LIMIT = false
// Valid range for an enchantment limit // Valid range for an enchantment limit
@JvmField @JvmField
val ENCHANT_LIMIT_RANGE = 1..255 val ENCHANT_LIMIT_RANGE = 1..255
// Default value for an enchantment multiplier // Default value for an enchantment multiplier
private const val DEFAULT_ENCHANT_VALUE = 0 private const val DEFAULT_ENCHANT_VALUE = 0
// Default value for debug logging // Default value for debug logging
private const val DEFAULT_DEBUG_LOG = false private const val DEFAULT_DEBUG_LOG = false
// Default value for debug logging // Default value for debug logging
private const val DEFAULT_VERBOSE_DEBUG_LOG = false private const val DEFAULT_VERBOSE_DEBUG_LOG = false
@ -155,6 +182,7 @@ object ConfigOptions {
.takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE } .takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE }
?: DEFAULT_SACRIFICE_ILLEGAL_COST ?: DEFAULT_SACRIFICE_ILLEGAL_COST
} }
/** /**
* Whether to remove repair cost limit * Whether to remove repair cost limit
*/ */
@ -218,7 +246,8 @@ object ConfigOptions {
* Get an array of key of basic config options * Get an array of key of basic config options
*/ */
fun getBasicConfigKeys(): Array<String> { fun getBasicConfigKeys(): Array<String> {
return arrayOf(DEFAULT_LIMIT_PATH, return arrayOf(
DEFAULT_LIMIT_PATH,
LIMIT_REPAIR_COST, LIMIT_REPAIR_COST,
LIMIT_REPAIR_VALUE, LIMIT_REPAIR_VALUE,
ITEM_REPAIR_COST, ITEM_REPAIR_COST,

View file

@ -34,9 +34,11 @@ object EnchantmentUtil {
if (!containsKey(enchantment)) { if (!containsKey(enchantment)) {
// Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions // Add the enchantment if it doesn't have conflicts, or if player is allowed to bypass enchantment restrictions
this[enchantment] = level this[enchantment] = level
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment); val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
if (!player.hasPermission(CustomAnvil.bypassFusePermission) && if (!player.hasPermission(CustomAnvil.bypassFusePermission) &&
(conflictType != ConflictType.NO_CONFLICT)){ (conflictType != ConflictType.NO_CONFLICT)
) {
CustomAnvil.verboseLog("Enchantment not yet in result list, but there is conflict (${enchantment.key}, conflict: $conflictType)") CustomAnvil.verboseLog("Enchantment not yet in result list, but there is conflict (${enchantment.key}, conflict: $conflictType)")
this.remove(enchantment) this.remove(enchantment)
} }
@ -45,9 +47,11 @@ object EnchantmentUtil {
// Enchantment already in result list // Enchantment already in result list
else { else {
// ... and they are conflicting // ... and they are conflicting
val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment) val conflictType =
ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys, mat, enchantment)
if ((conflictType != ConflictType.NO_CONFLICT) if ((conflictType != ConflictType.NO_CONFLICT)
&& !player.hasPermission(CustomAnvil.bypassFusePermission)){ && !player.hasPermission(CustomAnvil.bypassFusePermission)
) {
CustomAnvil.verboseLog("Enchantment already in result list, and they are conflicting (${enchantment.key}, conflict: $conflictType)") CustomAnvil.verboseLog("Enchantment already in result list, and they are conflicting (${enchantment.key}, conflict: $conflictType)")
return@forEach return@forEach
} }
@ -57,7 +61,9 @@ object EnchantmentUtil {
val newLevel = max(this[enchantment] ?: 0, other[enchantment] ?: 0) val newLevel = max(this[enchantment] ?: 0, other[enchantment] ?: 0)
// apply the greater of the two if non-zero // apply the greater of the two if non-zero
if (newLevel > 0) { this[enchantment] = newLevel } if (newLevel > 0) {
this[enchantment] = newLevel
}
} }
// ... and they're the same level // ... and they're the same level
else { else {
@ -70,7 +76,9 @@ object EnchantmentUtil {
ConfigOptions.enchantLimit(enchantment) ConfigOptions.enchantLimit(enchantment)
} }
newLevel = min(newLevel, maxLevel) newLevel = min(newLevel, maxLevel)
if (newLevel > 0) { this[enchantment] = newLevel } if (newLevel > 0) {
this[enchantment] = newLevel
}
} }
} }
} }

View file

@ -44,6 +44,7 @@ abstract class AbstractMaterialGroup(private val name: String) {
open fun getNonGroupInheritedMaterials(): EnumSet<Material> { open fun getNonGroupInheritedMaterials(): EnumSet<Material> {
return includedMaterial return includedMaterial
} }
/** /**
* Get the group non-inherited material as a set * Get the group non-inherited material as a set
*/ */

View file

@ -7,7 +7,8 @@ import org.bukkit.enchantments.Enchantment
class EnchantConflictGroup( class EnchantConflictGroup(
val name: String, val name: String,
private val cantConflict: AbstractMaterialGroup, private val cantConflict: AbstractMaterialGroup,
val minBeforeBlock: Int){ val minBeforeBlock: Int
) {
private val enchantments = HashSet<Enchantment>() private val enchantments = HashSet<Enchantment>()
@ -38,7 +39,7 @@ class EnchantConflictGroup(
} }
fun getCantConflictGroup(): AbstractMaterialGroup { fun getCantConflictGroup(): AbstractMaterialGroup {
return this.cantConflict; return this.cantConflict
} }
fun getEnchants(): HashSet<Enchantment> { fun getEnchants(): HashSet<Enchantment> {

View file

@ -11,13 +11,17 @@ class EnchantConflictManager {
companion object { companion object {
// Path for the enchantments list // Path for the enchantments list
const val ENCH_LIST_PATH = "enchantments" const val ENCH_LIST_PATH = "enchantments"
// Path for group list related to the conflict // Path for group list related to the conflict
const val CONFLICT_GROUP_PATH = "notAffectedGroups" const val CONFLICT_GROUP_PATH = "notAffectedGroups"
// Path for the maximum number of enchantment before validating the conflict // Path for the maximum number of enchantment before validating the conflict
const val ENCH_MAX_PATH = "maxEnchantmentBeforeConflict" const val ENCH_MAX_PATH = "maxEnchantmentBeforeConflict"
// Path for a flag: if the enchantment will be used in the last supported version // Path for a flag: if the enchantment will be used in the last supported version
// TODO maybe replace this system by a list of "future" enchantment. // TODO maybe replace this system by a list of "future" enchantment.
private const val FUTURE_USE_PATH = "useInFuture" private const val FUTURE_USE_PATH = "useInFuture"
// Default name for a joining group // Default name for a joining group
private const val DEFAULT_GROUP_NAME = "joinedGroup" private const val DEFAULT_GROUP_NAME = "joinedGroup"
} }
@ -34,19 +38,17 @@ class EnchantConflictManager {
for (key in keys) { for (key in keys) {
val section = config.getConfigurationSection(key)!! val section = config.getConfigurationSection(key)!!
val conflict = createConflict(section, itemManager, key) val conflict = createConflict(section, itemManager, key)
if(conflict != null){
addToMap(conflict) addToMap(conflict)
conflictList.add(conflict) conflictList.add(conflict)
} }
} }
}
// Add the conflict to the map // Add the conflict to the map
private fun addToMap(conflict: EnchantConflictGroup) { private fun addToMap(conflict: EnchantConflictGroup) {
conflict.getEnchants().forEach { enchant -> conflict.getEnchants().forEach { enchant ->
addConflictToConflictMap(enchant, conflict); addConflictToConflictMap(enchant, conflict)
} }
} }
@ -62,9 +64,11 @@ class EnchantConflictManager {
} }
// create and read a conflict from a yaml section // create and read a conflict from a yaml section
private fun createConflict(section: ConfigurationSection, private fun createConflict(
section: ConfigurationSection,
itemManager: ItemGroupManager, itemManager: ItemGroupManager,
conflictName: String): EnchantConflictGroup? { conflictName: String
): EnchantConflictGroup {
// Is it planed for the future // Is it planed for the future
val futureUse = section.getBoolean(FUTURE_USE_PATH, false) val futureUse = section.getBoolean(FUTURE_USE_PATH, false)
// Create conflict // Create conflict
@ -91,9 +95,11 @@ class EnchantConflictManager {
return conflict return conflict
} }
private fun createConflictObject(section: ConfigurationSection, private fun createConflictObject(
section: ConfigurationSection,
itemManager: ItemGroupManager, itemManager: ItemGroupManager,
conflictName: String): EnchantConflictGroup { conflictName: String
): EnchantConflictGroup {
// Get the maximum number of enchantment before validating the conflict // Get the maximum number of enchantment before validating the conflict
var minBeforeBlock = section.getInt(ENCH_MAX_PATH, 0) var minBeforeBlock = section.getInt(ENCH_MAX_PATH, 0)
if (minBeforeBlock < 0) { if (minBeforeBlock < 0) {
@ -112,7 +118,11 @@ class EnchantConflictManager {
return EnchantConflictGroup(conflictName, finalGroup, minBeforeBlock) return EnchantConflictGroup(conflictName, finalGroup, minBeforeBlock)
} }
private fun findGroup(groupName: String, itemManager: ItemGroupManager, conflictName: String): AbstractMaterialGroup { private fun findGroup(
groupName: String,
itemManager: ItemGroupManager,
conflictName: String
): AbstractMaterialGroup {
val group = itemManager.get(groupName) val group = itemManager.get(groupName)
if (group == null) { if (group == null) {
CustomAnvil.instance.logger.warning("Group $groupName do not exist but is ask by conflict $conflictName") CustomAnvil.instance.logger.warning("Group $groupName do not exist but is ask by conflict $conflictName")

View file

@ -4,17 +4,19 @@ import io.delilaheve.CustomAnvil
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import java.util.* import java.util.*
import kotlin.collections.LinkedHashMap
class ItemGroupManager { class ItemGroupManager {
companion object { companion object {
// Path for group type // Path for group type
private const val GROUP_TYPE_PATH = "type" private const val GROUP_TYPE_PATH = "type"
// Path for included items list // Path for included items list
private const val MATERIAL_LIST_PATH = "items" private const val MATERIAL_LIST_PATH = "items"
// Path for included groups list // Path for included groups list
private const val GROUP_LIST_PATH = "groups" private const val GROUP_LIST_PATH = "groups"
// Temporary list of elements in default config that are use in future // Temporary list of elements in default config that are use in future
private val FUTURE_MATERIAL = setOf("PIGLIN_HEAD", "BRUSH") private val FUTURE_MATERIAL = setOf("PIGLIN_HEAD", "BRUSH")
} }
@ -34,9 +36,11 @@ class ItemGroupManager {
} }
// Create group by key // Create group by key
private fun createGroup(config: ConfigurationSection, private fun createGroup(
config: ConfigurationSection,
keys: Set<String>, keys: Set<String>,
key: String): AbstractMaterialGroup { key: String
): AbstractMaterialGroup {
val groupSection = config.getConfigurationSection(key)!! val groupSection = config.getConfigurationSection(key)!!
val groupType = groupSection.getString(GROUP_TYPE_PATH, null) val groupType = groupSection.getString(GROUP_TYPE_PATH, null)
@ -57,10 +61,12 @@ class ItemGroupManager {
} }
// Read Group elements // Read Group elements
private fun readGroup(group: AbstractMaterialGroup, private fun readGroup(
group: AbstractMaterialGroup,
groupSection: ConfigurationSection, groupSection: ConfigurationSection,
config: ConfigurationSection, config: ConfigurationSection,
keys: Set<String>){ keys: Set<String>
) {
// Read material to include in this group policy // Read material to include in this group policy
val materialList = groupSection.getStringList(MATERIAL_LIST_PATH) val materialList = groupSection.getStringList(MATERIAL_LIST_PATH)
for (materialTemp in materialList) { for (materialTemp in materialList) {
@ -70,7 +76,8 @@ class ItemGroupManager {
// Check if we should warn the user // Check if we should warn the user
if (materialName !in FUTURE_MATERIAL) { if (materialName !in FUTURE_MATERIAL) {
CustomAnvil.instance.logger.warning( CustomAnvil.instance.logger.warning(
"Unknown material $materialTemp on group ${group.getName()}") "Unknown material $materialTemp on group ${group.getName()}"
)
} }
continue continue
@ -84,7 +91,8 @@ class ItemGroupManager {
for (groupName in groupList) { for (groupName in groupList) {
if (groupName !in keys) { if (groupName !in keys) {
CustomAnvil.instance.logger.warning( CustomAnvil.instance.logger.warning(
"Group $groupName do not exist but is included in group ${group.getName()}") "Group $groupName do not exist but is included in group ${group.getName()}"
)
continue continue
} }
// Get other group or create it if not yet created // Get other group or create it if not yet created
@ -96,9 +104,11 @@ class ItemGroupManager {
// Avoid self reference or it will create an infinite loop // Avoid self reference or it will create an infinite loop
if (otherGroup.isReferencing(group)) { if (otherGroup.isReferencing(group)) {
CustomAnvil.instance.logger.warning( CustomAnvil.instance.logger.warning(
"Group $groupName is on a reference loop with group ${group.getName()} !") "Group $groupName is on a reference loop with group ${group.getName()} !"
)
CustomAnvil.instance.logger.warning( CustomAnvil.instance.logger.warning(
"Please fix it in your item_groups config or the plugin will probably not work as expected.") "Please fix it in your item_groups config or the plugin will probably not work as expected."
)
continue continue
} }

View file

@ -31,12 +31,11 @@ object MetricsUtil {
*/ */
private fun getHashFromKey(section: ConfigurationSection, key: String): Int { private fun getHashFromKey(section: ConfigurationSection, key: String): Int {
// Key is assumend to exist // Key is assumend to exist
val resultHash: Int val resultHash = if (section.isConfigurationSection(key)) {
if(section.isConfigurationSection(key)){
val sectionResult = getConfigurationHash(section.getConfigurationSection(key)!!) val sectionResult = getConfigurationHash(section.getConfigurationSection(key)!!)
resultHash = key.hashCode() xor sectionResult key.hashCode() xor sectionResult
} else { } else {
resultHash = key.hashCode() xor section.getString(key).hashCode() key.hashCode() xor section.getString(key).hashCode()
} }
return resultHash.hashCode() return resultHash.hashCode()
} }
@ -83,12 +82,24 @@ object MetricsUtil {
isDefaultUnitRepairItemConfig = unitRepairItemConfigHash == unitRepairConfig isDefaultUnitRepairItemConfig = unitRepairItemConfigHash == unitRepairConfig
// If not default and debug flag active, print the hash. // If not default and debug flag active, print the hash.
if (ConfigOptions.debugLog) { if (ConfigOptions.debugLog) {
if(!isDefaultBaseConfig){CustomAnvil.log("baseConfig: $baseConfig")} if (!isDefaultBaseConfig) {
if(!isDefaultEnchantLimitsConfig){CustomAnvil.log("limitEnchantConfig: $limitEnchantConfig")} CustomAnvil.log("baseConfig: $baseConfig")
if(!isDefaultEnchantValuesConfig){CustomAnvil.log("enchantValueConfig: $enchantValueConfig")} }
if(!isDefaultEnchantConflictConfig){CustomAnvil.log("enchantConflictConfig: $enchantConflictConfig")} if (!isDefaultEnchantLimitsConfig) {
if(!isDefaultItemGroupsConfig){CustomAnvil.log("itemGroupConfig: $itemGroupConfig")} CustomAnvil.log("limitEnchantConfig: $limitEnchantConfig")
if(!isDefaultUnitRepairItemConfig){CustomAnvil.log("unitRepairConfig: $unitRepairConfig")} }
if (!isDefaultEnchantValuesConfig) {
CustomAnvil.log("enchantValueConfig: $enchantValueConfig")
}
if (!isDefaultEnchantConflictConfig) {
CustomAnvil.log("enchantConflictConfig: $enchantConflictConfig")
}
if (!isDefaultItemGroupsConfig) {
CustomAnvil.log("itemGroupConfig: $itemGroupConfig")
}
if (!isDefaultUnitRepairItemConfig) {
CustomAnvil.log("unitRepairConfig: $unitRepairConfig")
}
} }
} }
@ -96,18 +107,18 @@ object MetricsUtil {
fun notifyChange(holder: ConfigHolder, path: String) { fun notifyChange(holder: ConfigHolder, path: String) {
if (ConfigHolder.DEFAULT_CONFIG.equals(holder)) { if (ConfigHolder.DEFAULT_CONFIG.equals(holder)) {
if (path.startsWith(ConfigOptions.ENCHANT_LIMIT_ROOT + ".")) { if (path.startsWith(ConfigOptions.ENCHANT_LIMIT_ROOT + ".")) {
isDefaultEnchantLimitsConfig = false; isDefaultEnchantLimitsConfig = false
} else if (path.startsWith(ConfigOptions.ENCHANT_VALUES_ROOT + ".")) { } else if (path.startsWith(ConfigOptions.ENCHANT_VALUES_ROOT + ".")) {
isDefaultEnchantValuesConfig = false; isDefaultEnchantValuesConfig = false
} else { } else {
isDefaultBaseConfig = false; isDefaultBaseConfig = false
} }
} else if (ConfigHolder.CONFLICT_HOLDER.equals(holder)) { } else if (ConfigHolder.CONFLICT_HOLDER.equals(holder)) {
isDefaultEnchantConflictConfig = false; isDefaultEnchantConflictConfig = false
} else if (ConfigHolder.ITEM_GROUP_HOLDER.equals(holder)) { } else if (ConfigHolder.ITEM_GROUP_HOLDER.equals(holder)) {
isDefaultItemGroupsConfig = false; isDefaultItemGroupsConfig = false
} else if (ConfigHolder.UNIT_REPAIR_HOLDER.equals(holder)) { } else if (ConfigHolder.UNIT_REPAIR_HOLDER.equals(holder)) {
isDefaultUnitRepairItemConfig = false; isDefaultUnitRepairItemConfig = false
} }
} }

View file

@ -8,6 +8,7 @@ object UnitRepairUtil {
// Default value for user set default unit repair % // Default value for user set default unit repair %
private const val DEFAULT_DEFAULT_UNIT_REPAIR = 0.25 private const val DEFAULT_DEFAULT_UNIT_REPAIR = 0.25
// Path to user default unit repair value // Path to user default unit repair value
private const val UNIT_REPAIR_DEFAULT_PATH = "default_repair_amount" private const val UNIT_REPAIR_DEFAULT_PATH = "default_repair_amount"

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.3.2-A1 version: 1.3.2-A2
description: Allow to customise anvil mechanics description: Allow to customise anvil mechanics
api-version: 1.18 api-version: 1.18
load: POSTWORLD load: POSTWORLD