diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypass.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypass.java new file mode 100644 index 0000000..28a882b --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAClickResultBypass.java @@ -0,0 +1,45 @@ +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; + +public class CAClickResultBypass 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; + + @NotNull + public InventoryClickEvent getEvent() { + return event; + } + + public CAClickResultBypass(@NotNull InventoryClickEvent event) { + this.event = event; + } +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypass.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypass.java new file mode 100644 index 0000000..d8dc9b2 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAEarlyPreAnvilBypass.java @@ -0,0 +1,24 @@ +package xyz.alexcrea.cuanvil.api.event.listener; + +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.PrepareAnvilEvent; +import org.jetbrains.annotations.NotNull; + +public class CAEarlyPreAnvilBypass extends CAPreAnvilBypass { + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + @Override + public @NotNull HandlerList getHandlers() { + return HANDLERS; + } + + public CAEarlyPreAnvilBypass(@NotNull PrepareAnvilEvent event) { + super(event); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypass.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypass.java new file mode 100644 index 0000000..c802236 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CAPreAnvilBypass.java @@ -0,0 +1,46 @@ +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; + +public class CAPreAnvilBypass 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; + + @NotNull + public PrepareAnvilEvent getEvent() { + return event; + } + + public CAPreAnvilBypass(@NotNull PrepareAnvilEvent event) { + this.event = event; + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult.java b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult.java new file mode 100644 index 0000000..d92bd75 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/api/event/listener/CATreatAnvilResult.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.InventoryClickEvent; +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; + +public class CATreatAnvilResult 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 CATreatAnvilResult(@NotNull PrepareAnvilEvent event, AnvilUseType useType, @Nullable ItemStack result, int levelCost) { + this.event = event; + this.useType = useType; + this.result = result; + this.levelCost = levelCost; + } + + public @NotNull PrepareAnvilEvent getEvent() { + return event; + } + + public AnvilUseType getUseType() { + return useType; + } + + public @Nullable ItemStack getResult() { + return result; + } + + public void setResult(@Nullable ItemStack result) { + this.result = result; + } + + public int getLevelCost() { + return levelCost; + } + + 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..0303966 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.CAClickResultBypass +import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypass +import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypass +import xyz.alexcrea.cuanvil.api.event.listener.CATreatAnvilResult 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 = CAEarlyPreAnvilBypass(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 = CAPreAnvilBypass(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): CATreatAnvilResult? { + val treatEvent = CATreatAnvilResult(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: CATreatAnvilResult) { + 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 = CAClickResultBypass(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..282b3b2 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.CATreatAnvilResult import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEPreV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CAEEV5Enchantment import xyz.alexcrea.cuanvil.enchant.wrapped.CALegacyEEEnchantment @@ -188,9 +189,12 @@ 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: CATreatAnvilResult) { + val result = event.result + if(result == null) return + + val first: ItemStack = treatInput(event.event.inventory.getItem(0)) + val second: ItemStack = treatInput(event.event.inventory.getItem(1)) handleCombineMethod.invoke(this.usedAnvilListener, event, first, second, result) } diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt index 604c20f..c10359b 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/listener/PrepareAnvilListener.kt @@ -133,16 +133,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 +164,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 +248,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 +280,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 }