More config options Part 1 (#9)

- "Replace too expensive" config.
- Better basic configs.
- Better config range.
This commit is contained in:
alexcrea 2024-06-04 16:47:15 +00:00 committed by GitHub
commit 0d616d9fc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 399 additions and 184 deletions

View file

@ -15,14 +15,15 @@ the plugin can be downloaded on the
or [on GitHub](https://github.com/alexcrea/CustomAnvil/releases/latest)
---
**Custom Anvil** have the following features:
- Vanilla like default configuration
- Custom enchantment level limit
- Custom anvil recipes
- Custom enchant restrictions (allow unsafe enchantment only for a group of item or create new restriction)
- Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds)
- Custom XP cost for every aspect of the anvil
- Vanilla like default configuration.
- Custom enchantment level limit.
- Custom anvil recipes.
- Custom enchant restrictions (allow unsafe enchantment only for a group of item or create new restriction).
- Custom items of unit repairs (repair damaged with unit of "material", for example the repair of diamond sword by diamonds).
- Custom XP cost for every aspect of the anvil.
- Permissions to bypass level limit or enchantment restriction.
- Gui to configure the plugin in game
- Display xp cost instead of "to expensive" when above lv 40. (need ProtocoLib)
- Gui to configure the plugin in game.
---
### Permissions:
```yml
@ -54,8 +55,8 @@ Default configuration can be found on following links:
There is non known issue, if you find one please report the issue.
### Planned:
- Semi manual config update on pluign or minecraft update
- Check unknow registered enchantment & warn
- Warn admin on unsuported minecraft version
- Semi manual config update on plugin or minecraft update
- Check unknown registered enchantment & warn
- Warn admin on unsupported minecraft version

View file

@ -4,11 +4,14 @@ plugins {
}
group = "xyz.alexcrea"
version = "1.4.4"
version = "1.4.5"
repositories {
mavenCentral()
maven(url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
// ProtocoLib
maven (url = "https://repo.dmulloy2.net/repository/public/" )
}
dependencies {
@ -20,6 +23,8 @@ dependencies {
// Gui library
compileOnly("com.github.stefvanschie.inventoryframework:IF:0.10.13")
// Protocolib
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.0")

View file

@ -9,25 +9,26 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import xyz.alexcrea.cuanvil.gui.config.global.*;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.packet.PacketManager;
import java.util.Collections;
public class MainConfigGui extends ChestGui {
public final static MainConfigGui INSTANCE = new MainConfigGui();
private final static MainConfigGui INSTANCE = new MainConfigGui();
static {
INSTANCE.init();
public static MainConfigGui getInstance() {
return INSTANCE;
}
private MainConfigGui() {
super(3, "\u00A78Anvil Config", CustomAnvil.instance);
init(CustomAnvil.instance.packetManager);
}
private void init() {
private void init(PacketManager packetManager) {
Pattern pattern = new Pattern(
"000000000",
"012304567",
@ -47,7 +48,7 @@ public class MainConfigGui extends ChestGui {
basicConfigMeta.setLore(Collections.singletonList("\u00A77Click here to open basic config menu"));
basicConfigItemstack.setItemMeta(basicConfigMeta);
GuiItem basicConfigItem = GuiGlobalItems.goToGuiItem(basicConfigItemstack, BasicConfigGui.INSTANCE);
GuiItem basicConfigItem = GuiGlobalItems.goToGuiItem(basicConfigItemstack, new BasicConfigGui(packetManager));
pane.bindItem('1', basicConfigItem);
// enchant level limit item

View file

@ -9,6 +9,7 @@ import kotlin.ranges.IntRange;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.gui.ValueUpdatableGui;
import xyz.alexcrea.cuanvil.gui.config.MainConfigGui;
@ -17,7 +18,9 @@ import xyz.alexcrea.cuanvil.gui.config.settings.IntSettingsGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalItems;
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant;
import xyz.alexcrea.cuanvil.packet.PacketManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -26,17 +29,22 @@ import java.util.Collections;
*/
public class BasicConfigGui extends ValueUpdatableGui {
public final static BasicConfigGui INSTANCE = new BasicConfigGui();
private static BasicConfigGui INSTANCE;
static {
INSTANCE.init();
public static BasicConfigGui getInstance() {
return INSTANCE;
}
private final PacketManager packetManager;
/**
* Constructor of this Global gui for basic settings.
*/
private BasicConfigGui() {
super(3, "\u00A78Basic Config", CustomAnvil.instance);
public BasicConfigGui(PacketManager packetManager) {
super(4, "\u00A78Basic Config", CustomAnvil.instance);
INSTANCE = this;
this.packetManager = packetManager;
init();
}
PatternPane pane;
@ -47,67 +55,93 @@ public class BasicConfigGui extends ValueUpdatableGui {
private void init() {
Pattern pattern = new Pattern(
GuiSharedConstant.EMPTY_GUI_FULL_LINE,
"012345670",
"0L0T0I0S0",
"0C0R0U0r0",
"B00000000"
);
pane = new PatternPane(0, 0, 9, 3, pattern);
pane = new PatternPane(0, 0, 9, 4, pattern);
addPane(pane);
GuiGlobalItems.addBackItem(pane, MainConfigGui.INSTANCE);
GuiGlobalItems.addBackItem(pane, MainConfigGui.getInstance());
GuiGlobalItems.addBackgroundItem(pane);
prepareValues();
updateGuiValues();
}
private BoolSettingsGui.BoolSettingFactory limitRepairFactory;
private IntSettingsGui.IntSettingFactory repairCostFactory;
private GuiItem notNeededLimitValueItem;
private BoolSettingsGui.BoolSettingFactory removeRepairLimit;
private IntSettingsGui.IntSettingFactory itemRepairCost;
private IntSettingsGui.IntSettingFactory unitRepairCost;
private IntSettingsGui.IntSettingFactory itemRenameCost;
private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost;
private BoolSettingsGui.BoolSettingFactory capAnvilCostFactory; // L character
private GuiItem noCapRepairItem;
private IntSettingsGui.IntSettingFactory maxAnvilCostFactory; // C character
private GuiItem noMaxCostItem;
private BoolSettingsGui.BoolSettingFactory removeAnvilCostLimit; // R character
private BoolSettingsGui.BoolSettingFactory replaceTooExpensive; // T character
private IntSettingsGui.IntSettingFactory itemRepairCost; // I character
private IntSettingsGui.IntSettingFactory unitRepairCost; // U character
private IntSettingsGui.IntSettingFactory itemRenameCost; // r character
private IntSettingsGui.IntSettingFactory sacrificeIllegalEnchantCost; // S character
/**
* Prepare basic gui displayed items factory and static items..
*/
protected void prepareValues() {
// limit repair item
this.limitRepairFactory = BoolSettingsGui.boolFactory("\u00A78Limit Repair Cost ?", this,
ConfigOptions.LIMIT_REPAIR_COST, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_LIMIT_REPAIR,
"\u00A77Whether all anvil actions cost should be capped.",
"\u00A77If true, all anvil repairs will max out at the value of \u00A7aLimit Repair Value\u00A77.");
// repair cost item
IntRange range = ConfigOptions.REPAIR_LIMIT_RANGE;
this.repairCostFactory = IntSettingsGui.intFactory("\u00A78Repair Cost Limit", this,
ConfigOptions.LIMIT_REPAIR_VALUE, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList(
"\u00A77Value to limit repair costs to when \u00A7aLimit Repair Value\u00A77 is true.",
"\u00A77Valid values include \u00A7e1 \u00A77to \u00A7e39\u00A77: " +
"vanilla would display \u00A7e40+\u00A77 as \u00A7ctoo expensive\u00A77."
),
range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_LIMIT_REPAIR_VALUE,
1, 5, 10);
// repair cost not needed
// cap anvil cost
this.capAnvilCostFactory = BoolSettingsGui.boolFactory("\u00A78Cap Anvil Cost ?", this,
ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.CAP_ANVIL_COST, ConfigOptions.DEFAULT_CAP_ANVIL_COST,
"\u00A77All anvil cost will be capped to \u00A7aMax Anvil Cost\u00A77 if enabled.",
"\u00A77In other words:",
"\u00A77For any anvil cost greater than \u00A7aMax Anvil Cost\u00A77, Cost will be set to \u00A7aMax Anvil Cost\u00A77.");
// cap anvil cost not needed
ItemStack item = new ItemStack(Material.BARRIER);
ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.setDisplayName("\u00A7cLimit Repair Value");
meta.setLore(Collections.singletonList("\u00A77This config need \u00A7cLimit Repair Cost\u00A77 enabled."));
meta.setDisplayName("\u00A7cCap Anvil Cost ?");
meta.setLore(Collections.singletonList("\u00A77This config only work if \u00A7cLimit Repair Cost\u00A77 is disabled."));
item.setItemMeta(meta);
this.notNeededLimitValueItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
this.noCapRepairItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
// repair cost item
IntRange range = ConfigOptions.MAX_ANVIL_COST_RANGE;
this.maxAnvilCostFactory = IntSettingsGui.intFactory("\u00A78Max Anvil Cost", this,
ConfigOptions.MAX_ANVIL_COST, ConfigHolder.DEFAULT_CONFIG,
Arrays.asList(
"\u00A77Max cost the Anvil can get to.",
"\u00A77Valid values include \u00A7e0 \u00A77to \u00A7e1000\u00A77.",
"\u00A77Cost will be displayed as \u00A7cToo Expensive\u00A77:",
"\u00A77- If Cost is above \u00A7e39",
"\u00A77- And \u00A7eReplace Too Expensive\u00A77 is disabled"
),
range.getFirst(), range.getLast(),
ConfigOptions.DEFAULT_MAX_ANVIL_COST,
1, 5, 10);
// max anvil cost not needed
item = new ItemStack(Material.BARRIER);
meta = item.getItemMeta();
assert meta != null;
meta.setDisplayName("\u00A7cMax Anvil Cost");
meta.setLore(Collections.singletonList("\u00A77This config only work if \u00A7cLimit Repair Cost\u00A77 is disabled."));
item.setItemMeta(meta);
this.noMaxCostItem = new GuiItem(item, GuiGlobalActions.stayInPlace, CustomAnvil.instance);
// remove repair limit item
this.removeRepairLimit = BoolSettingsGui.boolFactory("\u00A78Remove Repair Limit ?", this,
ConfigOptions.REMOVE_REPAIR_LIMIT, ConfigHolder.DEFAULT_CONFIG, ConfigOptions.DEFAULT_REMOVE_LIMIT,
"\u00A77Whether the anvil's repair limit should be removed entirely.",
"\u00A77The anvil will still visually display \u00A7ctoo expensive\u00A77.",
"\u00A77However the action will be completable.");
this.removeAnvilCostLimit = BoolSettingsGui.boolFactory("\u00A78Remove Anvil Cost Limit ?", this,
ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REMOVE_ANVIL_COST_LIMIT, ConfigOptions.DEFAULT_REMOVE_ANVIL_COST_LIMIT,
"\u00A77Whether the anvil's cost limit should be removed entirely.",
"\u00A77The anvil will still visually display \u00A7cToo Expensive\u00A77 if \u00A7eReplace Too Expensive\u00A77 is disabled.",
"\u00A77However, the action will be completable if xp requirement is meet.");
// replace too expensive item
this.replaceTooExpensive = BoolSettingsGui.boolFactory("\u00A78Replace Too Expensive ?", this,
ConfigHolder.DEFAULT_CONFIG,
ConfigOptions.REPLACE_TOO_EXPENSIVE, ConfigOptions.DEFAULT_REPLACE_TOO_EXPENSIVE,
getReplaceToExpensiveLore());
// item repair cost
range = ConfigOptions.REPAIR_COST_RANGE;
@ -158,40 +192,63 @@ public class BasicConfigGui extends ValueUpdatableGui {
}
@NotNull
private String[] getReplaceToExpensiveLore() {
ArrayList<String> lore = new ArrayList<>();
lore.add("\u00A77Whenever anvil cost is above \u00A7e39\u00A77 should display the true price and not \u00A7cToo Expensive\u00A77.");
lore.add("\u00A77However, when bypassing \u00A7cToo Expensive\u00A77, anvil price will be displayed as \u00A7aGreen\u00A77.");
lore.add("\u00A77Even if cost is displayed as \u00A7aGreen\u00A77:");
lore.add("\u00A77If the player do not have the required xp level, the action will not be completable.");
if(!this.packetManager.isProtocoLibInstalled()){
lore.add("");
lore.add("\u00A74/!\\\u00A7cCaution/!\\ \u00A7cYou need ProtocoLib installed for this to work.");
}
String[] loreAsArray = new String[lore.size()];
return lore.toArray(loreAsArray);
}
@Override
public void updateGuiValues() {
// limit repair item
GuiItem limitRepairItem = this.limitRepairFactory.getItem();
pane.bindItem('1', limitRepairItem);
// rename cost item
GuiItem limitRepairValueItem;
if (this.limitRepairFactory.getConfiguredValue()) {
limitRepairValueItem = this.repairCostFactory.getItem(Material.EXPERIENCE_BOTTLE);
// limit and cap anvil cost item
GuiItem capAnvilCostItem;
GuiItem maxAnvilCostItem;
if (!this.removeAnvilCostLimit.getConfiguredValue()) {
capAnvilCostItem = this.capAnvilCostFactory.getItem("Cap Anvil Cost");
maxAnvilCostItem = this.maxAnvilCostFactory.getItem(Material.EXPERIENCE_BOTTLE, "Max Anvil Cost");
} else {
limitRepairValueItem = this.notNeededLimitValueItem;
capAnvilCostItem = this.noCapRepairItem;
maxAnvilCostItem = this.noMaxCostItem;
}
pane.bindItem('2', limitRepairValueItem);
pane.bindItem('L', capAnvilCostItem);
pane.bindItem('C', maxAnvilCostItem);
// remove repair limit item
GuiItem removeRepairLimitItem = this.removeRepairLimit.getItem();
pane.bindItem('3', removeRepairLimitItem);
GuiItem removeRepairLimitItem = this.removeAnvilCostLimit.getItem("Remove Anvil Cost Limit");
pane.bindItem('R', removeRepairLimitItem);
// replace too expensive item
GuiItem replaceToExpensiveItem = this.replaceTooExpensive.getItem();
pane.bindItem('T', replaceToExpensiveItem);
// item repair cost
GuiItem itemRepairCostItem = this.itemRepairCost.getItem(Material.ANVIL);
pane.bindItem('4', itemRepairCostItem);
pane.bindItem('I', itemRepairCostItem);
// unit repair cost
GuiItem unitRepairCostItem = this.unitRepairCost.getItem(Material.DIAMOND);
pane.bindItem('5', unitRepairCostItem);
pane.bindItem('U', unitRepairCostItem);
// item rename cost
GuiItem itemRenameCost = this.itemRenameCost.getItem(Material.NAME_TAG);
pane.bindItem('6', itemRenameCost);
pane.bindItem('r', itemRenameCost);
// sacrifice illegal enchant cost
GuiItem illegalCostItem = this.sacrificeIllegalEnchantCost.getItem(Material.ENCHANTED_BOOK);
pane.bindItem('7', illegalCostItem);
pane.bindItem('S', illegalCostItem);
update();
}

View file

@ -51,7 +51,7 @@ public class EnchantCostConfigGui extends AbstractEnchantConfigGui<EnchantCostSe
}
return EnchantCostSettingsGui.enchantCostFactory(prettyKey + " Level Cost", this,
SECTION_NAME + '.' + key, ConfigHolder.DEFAULT_CONFIG,
ConfigHolder.DEFAULT_CONFIG, SECTION_NAME + '.' + key,
Arrays.asList(
"\u00A77How many level should " + prettyKey,
"\u00A77cost when applied by book or by another item."

View file

@ -36,7 +36,7 @@ public abstract class ElementListConfigGui< T > extends ValueUpdatableGui {
// Back item panel
Pattern pattern = getBackgroundPattern();
this.backgroundPane = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern);
GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.INSTANCE);
GuiGlobalItems.addBackItem(this.backgroundPane, MainConfigGui.getInstance());
}

View file

@ -116,8 +116,8 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
return DoubleSettingGui.doubleFactory(
"\u00A70%\u00A78" + materialDisplayName +" Repair",
this,
this.parentMaterial.name().toLowerCase()+"."+materialName,
ConfigHolder.UNIT_REPAIR_HOLDER,
this.parentMaterial.name().toLowerCase()+"."+materialName,
Arrays.asList(
"\u00A77Click here to change how many \u00A7e% \u00A77of \u00A7a" + materialDisplayName,
"\u00A77Should get repaired by \u00A7e"+this.materialName

View file

@ -78,8 +78,8 @@ public class CustomRecipeSubSettingGui extends MappedToListSubSettingGui {
IntRange costRange = AnvilCustomRecipe.Companion.getXP_COST_CONFIG_RANGE();
this.exactCountFactory = BoolSettingsGui.boolFactory("\u00A78Exact count ?", this,
this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,
AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG);
ConfigHolder.DEFAULT_CONFIG,
this.anvilRecipe + "." + AnvilCustomRecipe.EXACT_COUNT_CONFIG, AnvilCustomRecipe.DEFAULT_EXACT_COUNT_CONFIG);
this.xpCostFactory = IntSettingsGui.intFactory("\u00A78Recipe Xp Cost", this,
this.anvilRecipe +"."+AnvilCustomRecipe.XP_COST_CONFIG, ConfigHolder.CUSTOM_RECIPE_HOLDER,

View file

@ -167,20 +167,21 @@ public class BoolSettingsGui extends AbstractSettingGui {
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param defaultVal Default value if not found on the config.
* @param displayLore Gui display item lore.
* @return A factory for a boolean setting gui.
*/
public static BoolSettingFactory boolFactory(@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config,
boolean defaultVal,
@NotNull ConfigHolder config,
@NotNull String configPath, boolean defaultVal,
String... displayLore) {
return new BoolSettingFactory(
title, parent,
configPath, config,
defaultVal, displayLore);
config,
configPath, defaultVal,
displayLore);
}
/**
@ -201,14 +202,14 @@ public class BoolSettingsGui extends AbstractSettingGui {
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param defaultVal Default value if not found on the config.
* @param displayLore Gui display item lore.
*/
protected BoolSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config,
@NotNull ConfigHolder config, @NotNull String configPath,
boolean defaultVal, String... displayLore) {
super(configPath, config);
this.title = title;

View file

@ -354,8 +354,8 @@ public class DoubleSettingGui extends AbstractSettingGui {
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param displayLore Gui display item lore.
* @param scale The scale of the decimal.
* @param asPercentage If we should display the value as a %.
@ -371,13 +371,15 @@ public class DoubleSettingGui extends AbstractSettingGui {
*/
@NotNull
public static DoubleSettingFactory doubleFactory(@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config,
@NotNull ConfigHolder config,
@NotNull String configPath,
@Nullable List<String> displayLore,
int scale, boolean asPercentage, boolean nullOnZero,
double min, double max, double defaultVal, double... steps) {
return new DoubleSettingFactory(
title, parent,
configPath, config,
config,
configPath,
displayLore,
scale, asPercentage, nullOnZero,
min, max, defaultVal, steps);
@ -408,8 +410,8 @@ public class DoubleSettingGui extends AbstractSettingGui {
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param displayLore Gui display item lore.
* @param scale The scale of the decimal.
* @param asPercentage If we should display the value as a %.
@ -424,7 +426,8 @@ public class DoubleSettingGui extends AbstractSettingGui {
*/
protected DoubleSettingFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config,
@NotNull ConfigHolder config,
@NotNull String configPath,
@Nullable List<String> displayLore,
int scale, boolean asPercentage, boolean nullOnZero,
double min, double max, double defaultVal, double... steps) {

View file

@ -243,8 +243,8 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
*
* @param title The title of the gui.
* @param parent Parent gui to go back when completed.
* @param configPath Configuration path of this setting.
* @param config Configuration holder of this setting.
* @param configPath Configuration path of this setting.
* @param displayLore Gui display item lore.
* @param min Minimum value of this setting.
* @param max Maximum value of this setting.
@ -258,7 +258,7 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
*/
public static EnchantCostSettingFactory enchantCostFactory(
@NotNull String title, @NotNull ValueUpdatableGui parent,
@NotNull String configPath, @NotNull ConfigHolder config,
@NotNull ConfigHolder config, @NotNull String configPath,
@Nullable List<String> displayLore,
int min, int max, int defaultItemVal, int defaultBookVal,
int... steps) {

View file

@ -46,7 +46,7 @@ public class GuiSharedConstant {
);
BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE = new PatternPane(0, 0, 9, 6, Pane.Priority.LOW, pattern);
GuiGlobalItems.addBackItem(BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE, MainConfigGui.INSTANCE);
GuiGlobalItems.addBackItem(BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE, MainConfigGui.getInstance());
GuiGlobalItems.addBackgroundItem(BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE);
BACK_TO_MAIN_MENU_BIG_LIST_DISPLAY_BACKGROUND_PANE.bindItem('1', GuiSharedConstant.SECONDARY_BACKGROUND_ITEM);

View file

@ -19,6 +19,7 @@ import org.bukkit.event.EventPriority.HIGHEST
import org.bukkit.event.Listener
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView.Property.REPAIR_COST
@ -26,6 +27,7 @@ import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.packet.PacketManager
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import kotlin.math.min
@ -34,7 +36,7 @@ import kotlin.math.min
/**
* Listener for anvil events
*/
class AnvilEventListener : Listener {
class AnvilEventListener(private val packetManager: PacketManager) : Listener {
companion object {
// Anvil's output slot
@ -97,7 +99,6 @@ class AnvilEventListener : Listener {
// Test for merge
if (first.canMergeWith(second)) {
val newEnchants = first.findEnchantments()
.combineWith(second.findEnchantments(), first.type, player)
val resultItem = first.clone()
@ -208,7 +209,6 @@ class AnvilEventListener : Listener {
if ((output == inventory.getItem(ANVIL_INPUT_LEFT))
|| !allowed
) {
event.result = Event.Result.DENY
return
}
@ -332,6 +332,13 @@ class AnvilEventListener : Listener {
repairCost += calculatePenalty(leftItem, null, resultCopy)
repairCost += resultAmount * ConfigOptions.unitRepairCost
if (
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost) {
repairCost = min(repairCost, ConfigOptions.maxAnvilCost)
}
if ((inventory.maximumRepairCost < repairCost)
|| (player.level < repairCost)
) return
@ -520,8 +527,11 @@ class AnvilEventListener : Listener {
ignoreRules: Boolean = false
) {
// Test repair cost limit
val finalAnvilCost = if (ConfigOptions.limitRepairCost && !ignoreRules) {
min(anvilCost, ConfigOptions.limitRepairValue)
val finalAnvilCost = if (
!ignoreRules &&
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost) {
min(anvilCost, ConfigOptions.maxAnvilCost)
} else {
anvilCost
}
@ -533,25 +543,45 @@ class AnvilEventListener : Listener {
.server
.scheduler
.runTask(CustomAnvil.instance, Runnable {
if (ConfigOptions.removeRepairLimit || ignoreRules) {
inventory.maximumRepairCost = Int.MAX_VALUE
} else{
inventory.maximumRepairCost = 40 // minecraft default
}
inventory.repairCost = finalAnvilCost
inventory.maximumRepairCost =
if (ConfigOptions.doRemoveCostLimit || ignoreRules)
{ Int.MAX_VALUE }
else
{ ConfigOptions.maxAnvilCost + 1 }
inventory.repairCost = finalAnvilCost
event.view.setProperty(REPAIR_COST, finalAnvilCost)
val player = event.view.player
if(player is Player){
if(player.gameMode != GameMode.CREATIVE ){
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
(finalAnvilCost >= 40) &&
finalAnvilCost < inventory.maximumRepairCost
packetManager.setInstantBuild(player, bypassToExpensive)
}
player.updateInventory()
}
})
}
@EventHandler
fun onAnvilClose(event: InventoryCloseEvent){
val player = event.player
if(event.inventory !is AnvilInventory) return
if(player is Player && GameMode.CREATIVE != player.gameMode){
packetManager.setInstantBuild(player, false)
}
}
}
private class SlotContainer(val type: SlotType, val slot: Int)
private enum class SlotType {
CURSOR,

View file

@ -8,6 +8,9 @@ import xyz.alexcrea.cuanvil.command.EditConfigExecutor
import xyz.alexcrea.cuanvil.command.ReloadExecutor
import xyz.alexcrea.cuanvil.config.ConfigHolder
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.util.Metrics
import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.io.File
@ -66,14 +69,20 @@ class CustomAnvil : JavaPlugin() {
instance.logger.info(message)
}
}
}
lateinit var packetManager: PacketManager
/**
* Setup plugin for use
*/
override fun onEnable() {
instance = this
val pluginManager = Bukkit.getPluginManager();
// Disable old plugin name if exist
val potentialPlugin = Bukkit.getPluginManager().getPlugin("UnsafeEnchantsPlus")
if (potentialPlugin != null) {
@ -82,9 +91,15 @@ class CustomAnvil : JavaPlugin() {
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
}
// Load ProtocolLib dependency if exist
packetManager = if(pluginManager.isPluginEnabled("ProtocolLib"))
{ ProtocoLibWrapper(); }
else
{ NoProtocoLib(); }
// Load chat listener
chatListener = ChatEventListener()
Bukkit.getPluginManager().registerEvents(chatListener, this)
pluginManager.registerEvents(chatListener, this)
// Load config
val success = ConfigHolder.loadConfig()
@ -98,7 +113,7 @@ class CustomAnvil : JavaPlugin() {
prepareCommand()
server.pluginManager.registerEvents(
AnvilEventListener(),
AnvilEventListener(packetManager),
this
)
}

View file

@ -10,14 +10,17 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder
*/
object ConfigOptions {
// Path for default enchantment limits
private const val DEFAULT_LIMIT_PATH = "default_limit"
// Path for limiting anvil cost
const val CAP_ANVIL_COST = "limit_repair_cost"
// Path for limiting repair cost
const val LIMIT_REPAIR_COST = "limit_repair_cost"
// Path for max anvil cost value
const val MAX_ANVIL_COST = "limit_repair_value"
// Path for repair value limit
const val LIMIT_REPAIR_VALUE = "limit_repair_value"
// Path for removing anvil cost limits
const val REMOVE_ANVIL_COST_LIMIT = "remove_repair_limit"
// Path for removing too expensive when unused
const val REPLACE_TOO_EXPENSIVE = "replace_too_expensive"
// Path for level cost on item repair
const val ITEM_REPAIR_COST = "item_repair_cost"
@ -31,12 +34,14 @@ object ConfigOptions {
// Path for level cost on illegal enchantment on sacrifice
const val SACRIFICE_ILLEGAL_COST = "sacrifice_illegal_enchant_cost"
// Path for removing repair cost limits
const val REMOVE_REPAIR_LIMIT = "remove_repair_limit"
// Path for default enchantment limits
private const val DEFAULT_LIMIT_PATH = "default_limit"
// Root path for enchantment limits
const val ENCHANT_LIMIT_ROOT = "enchant_limits"
// Root path for enchantment values
const val ENCHANT_VALUES_ROOT = "enchant_values"
@ -44,20 +49,25 @@ object ConfigOptions {
private const val KEY_BOOK = "book"
private const val KEY_ITEM = "item"
// Debug logging toggle path
private const val DEBUG_LOGGING = "debug_log"
// Debug verbose logging toggle path
private const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose"
// Default value for enchantment limits
private const val DEFAULT_ENCHANT_LIMIT = 5
// Default value for limiting repair cost
const val DEFAULT_LIMIT_REPAIR = false
const val DEFAULT_CAP_ANVIL_COST = false
// Default value for repair cost limit
const val DEFAULT_LIMIT_REPAIR_VALUE = 39
const val DEFAULT_MAX_ANVIL_COST = 39
// Default for removing repair cost limits
const val DEFAULT_REMOVE_ANVIL_COST_LIMIT = false
// Default for removing repair cost limits
const val DEFAULT_REPLACE_TOO_EXPENSIVE = false
// Default value for level cost on item repair
const val DEFAULT_ITEM_REPAIR_COST = 2
@ -71,31 +81,9 @@ object ConfigOptions {
// Default value for level cost on illegal enchantment on sacrifice
const val DEFAULT_SACRIFICE_ILLEGAL_COST = 1
// Valid range for repair cost limit
@JvmField
val REPAIR_LIMIT_RANGE = 1..39
// Valid range for repair cost
@JvmField
val REPAIR_COST_RANGE = 0..255
// Valid range for rename cost
@JvmField
val ITEM_RENAME_COST_RANGE = 0..255
// Valid range for illegal enchantment conflict cost
@JvmField
val SACRIFICE_ILLEGAL_COST_RANGE = 0..255
// Default for removing repair cost limits
const val DEFAULT_REMOVE_LIMIT = false
// Valid range for an enchantment limit
@JvmField
val ENCHANT_LIMIT_RANGE = 1..255
// Default value for an enchantment multiplier
private const val DEFAULT_ENCHANT_VALUE = 0
// Default value for enchantment limits
private const val DEFAULT_ENCHANT_LIMIT = 5
// Default value for debug logging
private const val DEFAULT_DEBUG_LOG = false
@ -103,36 +91,71 @@ object ConfigOptions {
// Default value for debug logging
private const val DEFAULT_VERBOSE_DEBUG_LOG = false
// Valid range for repair cost limit
@JvmField
val MAX_ANVIL_COST_RANGE = 0..1000
// Valid range for repair cost
@JvmField
val REPAIR_COST_RANGE = 0..1000
// Valid range for rename cost
@JvmField
val ITEM_RENAME_COST_RANGE = 0..1000
// Valid range for illegal enchantment conflict cost
@JvmField
val SACRIFICE_ILLEGAL_COST_RANGE = 0..1000
// Valid range for an enchantment limit
@JvmField
val ENCHANT_LIMIT_RANGE = 1..255
// Default value for an enchantment multiplier
private const val DEFAULT_ENCHANT_VALUE = 0
/**
* Default enchantment limit
* Whether to cap anvil costs
*/
private val defaultEnchantLimit: Int
val doCapCost: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
.getBoolean(CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST)
}
/**
* Whether to limit repair costs to the vanilla limit
* Value to limit anvil costs to
*/
val limitRepairCost: Boolean
val maxAnvilCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(LIMIT_REPAIR_COST, DEFAULT_LIMIT_REPAIR)
.getInt(MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST)
.takeIf { it in MAX_ANVIL_COST_RANGE }
?: DEFAULT_MAX_ANVIL_COST
}
/**
* Value to limit repair costs to
* Whether to remove anvil cost limit
*/
val limitRepairValue: Int
val doRemoveCostLimit: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(LIMIT_REPAIR_VALUE, DEFAULT_LIMIT_REPAIR_VALUE)
.takeIf { it in REPAIR_LIMIT_RANGE }
?: DEFAULT_LIMIT_REPAIR_VALUE
.getBoolean(REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT)
}
/**
* Whether to remove repair cost limit
*/
val doReplaceTooExpensive: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE)
}
/**
@ -184,13 +207,13 @@ object ConfigOptions {
}
/**
* Whether to remove repair cost limit
* Default enchantment limit
*/
val removeRepairLimit: Boolean
private val defaultEnchantLimit: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(REMOVE_REPAIR_LIMIT, DEFAULT_REMOVE_LIMIT)
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
}
/**
@ -292,13 +315,14 @@ object ConfigOptions {
fun getBasicConfigKeys(): Array<String> {
return arrayOf(
DEFAULT_LIMIT_PATH,
LIMIT_REPAIR_COST,
LIMIT_REPAIR_VALUE,
CAP_ANVIL_COST,
MAX_ANVIL_COST,
REPLACE_TOO_EXPENSIVE,
ITEM_REPAIR_COST,
UNIT_REPAIR_COST,
ITEM_RENAME_COST,
SACRIFICE_ILLEGAL_COST,
REMOVE_REPAIR_LIMIT
REMOVE_ANVIL_COST_LIMIT
)
}

View file

@ -16,7 +16,7 @@ class EditConfigExecutor : CommandExecutor {
return false
}
if (sender !is HumanEntity) return false
MainConfigGui.INSTANCE.show(sender)
MainConfigGui.getInstance().show(sender)
return true
}

View file

@ -36,7 +36,7 @@ class ReloadExecutor : CommandExecutor {
if (!ConfigHolder.reloadAllFromDisk(hardfail)) return false
// Then update all global gui containing value from config
BasicConfigGui.INSTANCE.updateGuiValues()
BasicConfigGui.getInstance()?.updateGuiValues()
EnchantCostConfigGui.INSTANCE.updateGuiValues()
EnchantLimitConfigGui.INSTANCE.updateGuiValues()

View file

@ -0,0 +1,13 @@
package xyz.alexcrea.cuanvil.packet
import org.bukkit.entity.Player
class NoProtocoLib: PacketManager {
override val isProtocoLibInstalled: Boolean
get() = false
// ProtocoLib not installed: We do nothing
override fun setInstantBuild(player: Player, instantBuild: Boolean) {}
}

View file

@ -0,0 +1,11 @@
package xyz.alexcrea.cuanvil.packet
import org.bukkit.entity.Player
interface PacketManager {
val isProtocoLibInstalled: Boolean
fun setInstantBuild(player: Player, instantBuild: Boolean)
}

View file

@ -0,0 +1,39 @@
package xyz.alexcrea.cuanvil.packet
import com.comphenix.protocol.PacketType
import com.comphenix.protocol.ProtocolLibrary
import com.comphenix.protocol.ProtocolManager
import com.comphenix.protocol.events.PacketContainer
import org.bukkit.entity.Player
import java.lang.reflect.InvocationTargetException
class ProtocoLibWrapper: PacketManager {
private val protocolManager: ProtocolManager = ProtocolLibrary.getProtocolManager();
override val isProtocoLibInstalled: Boolean
get() = true
override fun setInstantBuild(player: Player, instantBuild: Boolean) {
val packet = PacketContainer(PacketType.Play.Server.ABILITIES)
// Set player's properties
packet.float
.write(0, player.flySpeed / 2)
.write(1, player.walkSpeed / 2)
packet.booleans
.write(0, player.isInvulnerable)
.write(1, player.isFlying)
.write(2, player.allowFlight)
.write(3, instantBuild)
// Send packet
try {
protocolManager.sendServerPacket(player, packet)
} catch (e: InvocationTargetException) {
e.printStackTrace()
}
}
}

View file

@ -7,7 +7,7 @@ import xyz.alexcrea.cuanvil.config.ConfigHolder
object MetricsUtil {
private const val baseConfigHash = -1592940914
private const val baseConfigHash = 1000387384
private const val enchantLimitsConfigHash = -275034280
private const val enchantValuesConfigHash = -17048020
private const val enchantConflictConfigHash = 546475833

View file

@ -1,44 +1,58 @@
# Whether all anvil actions cost should be capped
# All anvil cost will be capped to limit_repair_value if enabled.
#
# If true, all anvil repairs will max out at the value of limit_repair_value
# In other words:
# For any anvil cost greater than limit_repair_value, Cost will be set to limit_repair_value.
limit_repair_cost: false
# Value to limit repair costs to when limit_repair_cost is true
# Max cost value the Anvil can get to.
#
# Valid values include 1 to 39 (vanilla will consider 40+ as "too expensive")
# Valid values include 0 to 1000.
# Cost will be displayed as "Too Expensive":
# - If Cost is above 39
# - And replace_too_expensive is disabled (false)
limit_repair_value: 39
# Whether the anvil's repair limit should be removed entirely
# Whether the anvil's cost limit should be removed entirely.
#
# The anvil will still visually display "too expensive" however the action will be completable
# The anvil will still visually display "Too Expensive" if "replace_too_expensive" is disabled
# However, the action will be completable if xp requirement is meet.
remove_repair_limit: false
# Whenever anvil cost is above 39 should display the true price and not "Too Expensive".
#
# However, when bypassing "Too Expensive", anvil price will be displayed as Green.
# If the action is not completable, the cost will still be displayed as "Too expensive".
# That mean you also need to change other settings like remove_repair_limit or limit_repair_cost.
#
# Require ProtocoLib.
replace_too_expensive: false
# XP Level amount added to the anvil when the item is repaired by another item of the same type
#
# Valid values include 0 to 255
# Valid values include 0 to 1000
item_repair_cost: 2
# XP Level amount added to the anvil when the item is renamed
#
# Valid values include 0 to 1000
item_rename_cost: 1
# XP Level amount added to the anvil when the item is repaired by an "unit"
# For example: a Diamond on a Diamond Sword
# What's considered unit for what can be edited on the unit repair configuration.
#
# Valid values include 0 to 255
# Valid values include 0 to 1000
unit_repair_cost: 1
# XP Level amount added to the anvil when the item is renamed
#
# Valid values include 0 to 255
item_rename_cost: 1
# XP Level amount added to the anvil when a sacrifice enchantment
# conflict with one of the left item enchantment
#
# Valid values include 0 to 255
# Valid values include 0 to 1000
sacrifice_illegal_enchant_cost: 1
# Default limit to apply to any enchants missing from override_limits
#
# Valid values include 1 to 255
# Valid values include 1 to 1000
default_limit: 5
# Override limits for specific enchants
@ -229,4 +243,4 @@ debug_log: false
# Whether to show verbose debug logging
debug_log_verbose: false
configVersion: 1.4.3
configVersion: 1.4.5

View file

@ -1,7 +1,7 @@
main: io.delilaheve.CustomAnvil
name: CustomAnvil
prefix: "Custom Anvil"
version: 1.4.4
version: 1.4.5
description: Allow to customise anvil mechanics
api-version: 1.18
load: POSTWORLD
@ -44,4 +44,5 @@ permissions:
# soft depend on old name, so I can disable it if it is on the same server
# as it is the old name for this plugin
softdepend:
- UnsafeEnchantsPlus
- UnsafeEnchantsPlus
- ProtocolLib