diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java
index 24691db..67d27a8 100644
--- a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEvent.java
@@ -3,6 +3,23 @@ package xyz.alexcrea.cuanvil.api.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+/**
+ * Called when the configuration of CustomAnvil is ready.
+ * It is called either on the plugin startup or on the plugin config reload.
+ *
+ * If you want to listen to the first trigger of this event (first configuration load. aka plugin load)
+ * you will need to register the listener on your plugin onEnable or earlier
+ *
+ * This event indicate that can start to register your recipes, item groups and conflicts.
+ * The vanilla and custom enchantments should already have been provided to CustomAnvil.
+ * Configuration can be changed any time after this event is triggered but never before.
+ *
+ * use {@link xyz.alexcrea.cuanvil.api.ConflictAPI ConflictApi},
+ * {@link xyz.alexcrea.cuanvil.gui.config.global.CustomRecipeConfigGui CustomRecipeConfigGui},
+ * {@link xyz.alexcrea.cuanvil.api.MaterialGroupApi MaterialGroupApi}
+ * and {@link xyz.alexcrea.cuanvil.api.UnitRepairApi UnitRepairApi}
+ * to add/remove/edit configurations
+ */
public class CAConfigReadyEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java
index 3e2fdf8..3ffe372 100644
--- a/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEvent.java
@@ -3,6 +3,17 @@ package xyz.alexcrea.cuanvil.api.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
+/**
+ * Called when custom anvil is ready to accept registration on custom enchantment.
+ *
+ * If you want to listen this event
+ * you will need to register the listener on your plugin onEnable or earlier
+ *
+ * Custom enchantments may be registered later but may cause issue if registered too later
+ * (after configuration loading phase. see {@link CAConfigReadyEvent})
+ *
+ * use {@link xyz.alexcrea.cuanvil.api.EnchantmentApi EnchantmentApi} to register and unregister your custom enchantments
+ */
public class CAEnchantRegistryReadyEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java
new file mode 100644
index 0000000..a27c65e
--- /dev/null
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypassEvent.java
@@ -0,0 +1,63 @@
+package xyz.alexcrea.cuanvil.api.event.listener;
+
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called before custom anvil process the click on the result on the anvil inventory.
+ *
+ * This event is called after checking that the inventory is an anvil inventory and that the click is on the result slot
+ * but before checking if the player has the custom anvil affected permission.
+ *
+ * This event being cancelled will make CustomAnvil abort the click on result process.
+ *
+ * Most of the time you would likely need {@link CAPreAnvilBypassEvent} or {@link CAEarlyPreAnvilBypassEvent}
+ * for this event to be useful.
+ *
+ * There is also {@link CATreatAnvilResultEvent} that may be better for some use case.
+ */
+public class CAClickResultBypassEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ private boolean cancelled = false;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ private final InventoryClickEvent event;
+
+ /**
+ * Get the bukkit inventory click event causing to this event
+ *
+ * @return The click event causing to this event
+ */
+ @NotNull
+ public InventoryClickEvent getEvent() {
+ return event;
+ }
+
+ public CAClickResultBypassEvent(@NotNull InventoryClickEvent event) {
+ this.event = event;
+ }
+}
diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java
new file mode 100644
index 0000000..2fbd275
--- /dev/null
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypassEvent.java
@@ -0,0 +1,63 @@
+package xyz.alexcrea.cuanvil.api.event.listener;
+
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.inventory.PrepareAnvilEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called before custom anvil process the prepare anvil event.
+ *
+ * This event will always get called when CustomAnvil need to handle
+ *
+ * This event being cancelled will make CustomAnvil abort the anvil process.
+ *
+ * You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
+ *
+ * It is also recommended that you read about {@link CAPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
+ * as your use case may be more prone to use theses.
+ */
+public class CAEarlyPreAnvilBypassEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ private boolean cancelled = false;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ private final PrepareAnvilEvent event;
+
+ /**
+ * Get the bukkit pre anvil event causing this event
+ *
+ * @return The pre anvil event causing to this event
+ */
+ @NotNull
+ public PrepareAnvilEvent getEvent() {
+ return event;
+ }
+
+ public CAEarlyPreAnvilBypassEvent(@NotNull PrepareAnvilEvent event) {
+ this.event = event;
+ }
+
+}
diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java
new file mode 100644
index 0000000..18334e3
--- /dev/null
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypassEvent.java
@@ -0,0 +1,66 @@
+package xyz.alexcrea.cuanvil.api.event.listener;
+
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.inventory.PrepareAnvilEvent;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Called before custom anvil process the prepare anvil event.
+ *
+ * This event is called after {@link CAEarlyPreAnvilBypassEvent},
+ * after checking that there is at least an item on the left slot
+ * and after checking if any of the 2 item is marked as immutable
+ * but before checking if the player has the custom anvil affected permission.
+ *
+ * This event being cancelled will make CustomAnvil abort the anvil process.
+ *
+ * You should also use {@link CAClickResultBypassEvent} if you want to use this event for something useful.
+ *
+ * It is also recommended that you read about {@link CAEarlyPreAnvilBypassEvent} and {@link CATreatAnvilResultEvent}
+ * as your use case may be more prone to use theses.
+ */
+public class CAPreAnvilBypassEvent extends Event implements Cancellable {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ private boolean cancelled = false;
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ this.cancelled = cancel;
+ }
+
+ @NotNull
+ private final PrepareAnvilEvent event;
+
+ /**
+ * Get the bukkit pre anvil event causing this event
+ *
+ * @return The pre anvil event causing this event
+ */
+ @NotNull
+ public PrepareAnvilEvent getEvent() {
+ return event;
+ }
+
+ public CAPreAnvilBypassEvent(@NotNull PrepareAnvilEvent event) {
+ this.event = event;
+ }
+
+}
diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResultEvent.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResultEvent.java
new file mode 100644
index 0000000..1675d1a
--- /dev/null
+++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResultEvent.java
@@ -0,0 +1,131 @@
+package xyz.alexcrea.cuanvil.api.event.listener;
+
+import org.bukkit.event.Event;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.inventory.PrepareAnvilEvent;
+import org.bukkit.inventory.ItemStack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import xyz.alexcrea.cuanvil.util.AnvilUseType;
+
+/**
+ * Called after custom anvil processed the click on the result on the anvil inventory.
+ * This event should be used to modify the result of an anvil use.
+ *
+ * You may also want to check {@link CAClickResultBypassEvent},
+ * {@link CAPreAnvilBypassEvent}
+ * and {@link CAEarlyPreAnvilBypassEvent} for your use case
+ *
+ * A null result will cancel this pre anvil event
+ */
+@SuppressWarnings("unused")
+public class CATreatAnvilResultEvent extends Event {
+
+ private static final HandlerList HANDLERS = new HandlerList();
+
+ public static HandlerList getHandlerList() {
+ return HANDLERS;
+ }
+
+ @Override
+ public @NotNull HandlerList getHandlers() {
+ return HANDLERS;
+ }
+
+ @NotNull
+ private final PrepareAnvilEvent event;
+
+ private final AnvilUseType useType;
+
+ @Nullable
+ private ItemStack result;
+
+ private int levelCost;
+
+ public CATreatAnvilResultEvent(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, int levelCost) {
+ this.event = event;
+ this.useType = useType;
+ this.result = result;
+ this.levelCost = levelCost;
+ }
+
+ /**
+ * Get the bukkit inventory click event causing to this event.
+ *
+ * @return The click event causing to this event.
+ */
+ public @NotNull PrepareAnvilEvent getEvent() {
+ return event;
+ }
+
+ /**
+ * Get the type of use source of the result.
+ *
+ * @return The craft use type.
+ */
+ public AnvilUseType getUseType() {
+ return useType;
+ }
+
+ /**
+ * Get the current result
+ *
+ * note that it will not be null unless another listener previously set it to null.
+ *
+ * @return The current result.
+ */
+ public @Nullable ItemStack getResult() {
+ return result;
+ }
+
+ /**
+ * Set the current result
+ *
+ * note that a null result will cancel this anvil use.
+ *
+ * @param result The new result
+ */
+ public void setResult(@Nullable ItemStack result) {
+ this.result = result;
+ }
+
+ /**
+ * Get the level cost displayed on the anvil.
+ *
Important note:
+ * the final price are re calculated on click for the following use case:
+ *
+ * - Custom craft
+ * - Unit repair
+ * - Lore edit
+ *
+ * This value will be used as final price for:
+ * Item merge
+ * Item rename
+ *
+ *
+ * @return The current cost.
+ */
+ public int getLevelCost() {
+ return levelCost;
+ }
+
+ /**
+ * Set the level cost displayed on the anvil.
+ * Important note:
+ * the final price are re calculated on click for the following use case:
+ *
+ * - Custom craft
+ * - Unit repair
+ * - Lore edit
+ *
+ * This value will be used as final price for:
+ * Item merge
+ * Item rename
+ *
+ *
+ * @param levelCost The new cost.
+ */
+ public void setLevelCost(int levelCost) {
+ this.levelCost = levelCost;
+ }
+}
diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt
index 85d326f..09980b5 100644
--- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt
+++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/DependencyManager.kt
@@ -8,6 +8,10 @@ import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
+import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
+import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
+import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent
+import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.datapack.DataPackDependency
import xyz.alexcrea.cuanvil.dependency.gui.ExternGuiTester
@@ -19,6 +23,7 @@ import xyz.alexcrea.cuanvil.dependency.scheduler.BukkitScheduler
import xyz.alexcrea.cuanvil.dependency.scheduler.FoliaScheduler
import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
+import xyz.alexcrea.cuanvil.util.AnvilUseType
import java.util.logging.Level
object DependencyManager {
@@ -139,10 +144,14 @@ object DependencyManager {
}
private fun earlyUnsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
- var bypass = false
+ // Run the event
+ val bypassEvent = CAEarlyPreAnvilBypassEvent(event)
+ Bukkit.getPluginManager().callEvent(bypassEvent)
+
+ var bypass = bypassEvent.isCancelled
// Test if the inventory is a gui(version specific)
- if (externGuiTester?.testIfGui(event.view) == true) bypass = true
+ if (!bypass && (externGuiTester?.testIfGui(event.view) == true)) bypass = true
return bypass
}
@@ -171,10 +180,14 @@ object DependencyManager {
}
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
- var bypass = false
+ // Run the event
+ val bypassEvent = CAPreAnvilBypassEvent(event)
+ Bukkit.getPluginManager().callEvent(bypassEvent)
+
+ var bypass = bypassEvent.isCancelled
// Test if disenchantment used prepare anvil
- if (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true) bypass = true
+ if (!bypass && (disenchantmentCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
// Test heaven bags used prepare anvil
if (!bypass && (havenBagsCompatibility?.testPrepareAnvil(event, player) == true)) bypass = true
@@ -189,11 +202,12 @@ object DependencyManager {
return bypass
}
- // Return true only if error occurred (and so should bypass rest)
- fun tryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack): Boolean {
+ // Return null if there was an issue
+ fun tryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack, useType: AnvilUseType, cost: Int): CATreatAnvilResultEvent? {
+ val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost)
try {
- unsafeTryTreatAnvilResult(event, result)
- return false
+ unsafeTryTreatAnvilResult(treatEvent)
+ return treatEvent;
} catch (e: Exception) {
CustomAnvil.instance.logger.log(
Level.SEVERE,
@@ -209,12 +223,14 @@ object DependencyManager {
"[" + ChatColor.YELLOW.toString() + "CustomAnvil" + ChatColor.WHITE.toString() + "] " +
ChatColor.RED.toString() + "Error while handling the anvil."
)
- return true
+ return null
}
}
- private fun unsafeTryTreatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) {
- excellentEnchantsCompatibility?.treatAnvilResult(event, result)
+ private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
+ Bukkit.getPluginManager().callEvent(event)
+
+ excellentEnchantsCompatibility?.treatAnvilResult(event)
}
// Return true if should bypass (either by a dependency or error)
@@ -241,10 +257,14 @@ object DependencyManager {
}
private fun unsafeTryClickAnvilResultBypass(event: InventoryClickEvent, inventory: AnvilInventory): Boolean {
- var bypass = false
+ // Run the event
+ val bypassEvent = CAClickResultBypassEvent(event)
+ Bukkit.getPluginManager().callEvent(bypassEvent)
+
+ var bypass = bypassEvent.isCancelled
// Test if disenchantment used event click
- if (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true) bypass = true
+ if (!bypass && (disenchantmentCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
// Test if haven bag used event click
if (!bypass && (havenBagsCompatibility?.testAnvilResult(event, inventory) == true)) bypass = true
diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt
index 301460b..2aee624 100644
--- a/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt
+++ b/src/main/kotlin/xyz/alexcrea/cuanvil/dependency/plugins/ExcellentEnchantsDependency.kt
@@ -8,6 +8,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.plugin.RegisteredListener
import xyz.alexcrea.cuanvil.api.EnchantmentApi
+import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResultEvent
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment
import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment
@@ -46,7 +47,7 @@ class ExcellentEnchantsDependency {
}
}
- if(listenerVersion == null){
+ if (listenerVersion == null) {
CustomAnvil.instance.logger.severe("Found issue with listener of Excellent Enchants. compatiblity is broken. please contact CustomAnvil devs")
}
@@ -124,20 +125,23 @@ class ExcellentEnchantsDependency {
toUnregister.add(registeredListener)
}
}
+
ListenerVersion.PRE_V5 -> {
if (listener is PreV5AnvilListener) {
this.preV5AnvilListener = listener
toUnregister.add(registeredListener)
}
}
+
ListenerVersion.LEGACY -> {
if (listener is LegacyAnvilListener) {
this.legacyAnvilListener = listener
toUnregister.add(registeredListener)
}
}
+
null -> {
- }
+ }
}
}
@@ -188,11 +192,14 @@ class ExcellentEnchantsDependency {
return handleRechargeMethod.invoke(this.usedAnvilListener, event, first, second) as Boolean
}
- fun treatAnvilResult(event: PrepareAnvilEvent, result: ItemStack) {
- val first: ItemStack = treatInput(event.inventory.getItem(0))
- val second: ItemStack = treatInput(event.inventory.getItem(1))
+ fun treatAnvilResult(event: CATreatAnvilResultEvent) {
+ val result = event.result
+ if (result == null) return
- handleCombineMethod.invoke(this.usedAnvilListener, event, first, second, result)
+ val first: ItemStack = treatInput(event.event.inventory.getItem(0))
+ val second: ItemStack = treatInput(event.event.inventory.getItem(1))
+
+ handleCombineMethod.invoke(this.usedAnvilListener, event.event, first, second, result)
}
fun testAnvilResult(event: InventoryClickEvent): Any {
diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt
index 0e9141f..64e43d1 100644
--- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt
+++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/AnvilResultListener.kt
@@ -46,7 +46,6 @@ class AnvilResultListener : Listener {
@EventHandler(ignoreCancelled = true)
fun anvilExtractionCheck(event: InventoryClickEvent) {
val player = event.whoClicked as? Player ?: return
- if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
val inventory = event.inventory as? AnvilInventory ?: return
if (event.rawSlot != ANVIL_OUTPUT_SLOT) {
@@ -56,6 +55,8 @@ class AnvilResultListener : Listener {
// Test if the event should bypass custom anvil.
if (DependencyManager.tryClickAnvilResultBypass(event, inventory)) return
+ if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
+
val output = inventory.getItem(ANVIL_OUTPUT_SLOT) ?: return
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT)
diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt
index 604c20f..dd1f5b9 100644
--- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt
+++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt
@@ -46,11 +46,15 @@ class PrepareAnvilListener : Listener {
fun anvilCombineCheck(event: PrepareAnvilEvent) {
// Should find player
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
+ val inventory = event.inventory
// Test if custom anvil is bypassed before immutability test
- if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) return
+ if (DependencyManager.earlyTryEventPreAnvilBypass(event, player)) {
+ // even if we got bypassed we still want to set price
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, event.inventory.repairCost)
+ return
+ }
- val inventory = event.inventory
val first = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val second = inventory.getItem(ANVIL_INPUT_RIGHT)
@@ -62,7 +66,11 @@ class PrepareAnvilListener : Listener {
}
// Test if the event should bypass custom anvil.
- if (DependencyManager.tryEventPreAnvilBypass(event, player)) return
+ if (DependencyManager.tryEventPreAnvilBypass(event, player)) {
+ // even if we got bypassed we still want to set price
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, event.inventory.repairCost)
+ return
+ }
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
@@ -133,16 +141,20 @@ class PrepareAnvilListener : Listener {
val resultItem: ItemStack = recipe.resultItem!!.clone()
resultItem.amount *= amount
- event.result = resultItem
- if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
-
+ // Maybe add an option on custom craft to ignore/not ignore penalty ??
val xpCost = recipe.determineCost(amount, first, resultItem)
val levelCost =
if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
else AnvilXpUtil.calculateLevelForXp(xpCost)
- AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, levelCost, true)
+ val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.CUSTOM_CRAFT, levelCost)
+ if (finalResult == null) return false
+
+ event.result = finalResult.result
+ if (finalResult.result == null) return false
+
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost, true)
return true
}
@@ -160,12 +172,15 @@ class PrepareAnvilListener : Listener {
return
}
- event.result = resultItem
- if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
-
anvilCost += AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
- AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
+ val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.RENAME_ONLY, anvilCost)
+ if (finalResult == null) return
+
+ event.result = finalResult.result
+ if (finalResult.result == null) return
+
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
@@ -241,10 +256,13 @@ class PrepareAnvilListener : Listener {
anvilCost += handleRename(resultItem, inventory, player)
// Finally, we set result
- event.result = resultItem
- if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return
+ val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.MERGE, anvilCost)
+ if (finalResult == null) return
- AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
+ event.result = finalResult.result
+ if (finalResult.result == null) return
+
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
}
// return true if there is a valid unit repair with these ingredients
@@ -270,10 +288,14 @@ class PrepareAnvilListener : Listener {
event.result = null
return true
}
- event.result = resultItem
- if (DependencyManager.tryTreatAnvilResult(event, resultItem)) return true
- AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, anvilCost)
+ val finalResult = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.UNIT_REPAIR, anvilCost)
+ if (finalResult == null) return false
+
+ event.result = finalResult.result
+ if (finalResult.result == null) return false
+
+ AnvilXpUtil.setAnvilInvXp(inventory, event.view, player, finalResult.levelCost)
return true
}
diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEventTest.java b/src/test/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEventTest.java
new file mode 100644
index 0000000..ff73a59
--- /dev/null
+++ b/src/test/java/xyz/alexcrea/cuanvil/api/event/CAConfigReadyEventTest.java
@@ -0,0 +1,49 @@
+package xyz.alexcrea.cuanvil.api.event;
+
+import io.delilaheve.CustomAnvil;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockbukkit.mockbukkit.MockBukkit;
+import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher;
+import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
+
+public class CAConfigReadyEventTest extends SharedOnlyMockBukkit {
+
+ private CustomAnvil plugin;
+
+ @Test
+ public void startup() {
+ boolean beforeStart = PluginManagerFiredEventClassMatcher
+ .hasNotFiredEventInstance(CAConfigReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(beforeStart, "Somehow, event fired before plugin being loaded ?");
+
+ // Load the plugin
+ plugin = MockBukkit.load(CustomAnvil.class);
+
+ boolean postStart = PluginManagerFiredEventClassMatcher
+ .hasNotFiredEventInstance(CAConfigReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(postStart, "Event fired before plugin finished being loaded");
+
+ // Config load phase
+ server.getScheduler().performOneTick();
+ boolean postConfig = PluginManagerFiredEventClassMatcher
+ .hasFiredEventInstance(CAConfigReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(postConfig, "Event did not fire after the config phase");
+ }
+
+ @AfterEach
+ public void pluginTeardown() {
+ if (plugin != null) {
+ server.getPluginManager().disablePlugin(plugin);
+ plugin = null;
+ }
+ }
+
+}
diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEventTest.java b/src/test/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEventTest.java
new file mode 100644
index 0000000..2c79388
--- /dev/null
+++ b/src/test/java/xyz/alexcrea/cuanvil/api/event/CAEnchantRegistryReadyEventTest.java
@@ -0,0 +1,49 @@
+package xyz.alexcrea.cuanvil.api.event;
+
+import io.delilaheve.CustomAnvil;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.mockbukkit.mockbukkit.MockBukkit;
+import org.mockbukkit.mockbukkit.matcher.plugin.PluginManagerFiredEventClassMatcher;
+import xyz.alexcrea.cuanvil.tests.SharedOnlyMockBukkit;
+
+public class CAEnchantRegistryReadyEventTest extends SharedOnlyMockBukkit {
+
+ private CustomAnvil plugin;
+
+ @Test
+ public void startup() {
+ boolean beforeStart = PluginManagerFiredEventClassMatcher
+ .hasNotFiredEventInstance(CAEnchantRegistryReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(beforeStart, "Somehow, event fired before plugin being loaded ?");
+
+ // Load the plugin
+ plugin = MockBukkit.load(CustomAnvil.class);
+
+ boolean postStart = PluginManagerFiredEventClassMatcher
+ .hasNotFiredEventInstance(CAEnchantRegistryReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(postStart, "Event fired before plugin finished being loaded");
+
+ // Config load phase
+ server.getScheduler().performOneTick();
+ boolean postConfig = PluginManagerFiredEventClassMatcher
+ .hasFiredEventInstance(CAEnchantRegistryReadyEvent.class)
+ .matches(server.getPluginManager());
+
+ Assertions.assertTrue(postConfig, "Event did not fire after the config phase");
+ }
+
+ @AfterEach
+ public void pluginTeardown() {
+ if (plugin != null) {
+ server.getPluginManager().disablePlugin(plugin);
+ plugin = null;
+ }
+ }
+
+}